From 06fdb9a42239c2df88ea6ee771f2ecdcc76baf0c Mon Sep 17 00:00:00 2001 From: Antonio Pantano Date: Mon, 30 Nov 2015 18:39:56 +0100 Subject: [PATCH 1/2] The Angual module now check if the Drupal site has CleanUrls enablend prepending the query path with '/?q' if not, or with just '/' otherwise' fixing a problem with Drupal web sites where the CleanURLs module is enabled --- .gitignore | 4 +++- build/angular-drupal.min.js | 4 ++-- src/angular-drupal.js | 37 +++++++++++++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index ca235a2..67a509f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ node_modules app/bower_components npm-debug.log - +.idea/ +.DS_Store +.directory diff --git a/build/angular-drupal.min.js b/build/angular-drupal.min.js index 0df19f7..7b3dff9 100644 --- a/build/angular-drupal.min.js +++ b/build/angular-drupal.min.js @@ -1,2 +1,2 @@ -/*! angular-drupal 2015-07-16 */ -function drupal(a,b,c,d){var e=c.sitePath,f=e+"/?q="+c.endpoint;this.sitePath=e,this.restPath=f,this.token=function(){if("undefined"!=typeof this.drupal){if(this.drupal.drupalToken)return console.log('grabbed token from "this" memory: '+d),b(function(a,b){setTimeout(function(){a(this.drupal.drupalToken)},100)})}else if(d)return console.log("grabbed token from memory: "+d),b(function(a,b){setTimeout(function(){a(d)},100)});return a.get(e+"/?q=services/session/token").then(function(a){return 200==a.status?d=a.data:void 0})},this.connect=function(){var b="undefined"!=typeof this.token?this.token:this.drupal.token;return b().then(function(b){return a({method:"POST",url:f+"/system/connect.json",headers:{"X-CSRF-Token":b}}).then(function(a){return 200==a.status?a.data:void 0})})},this.user_login=function(b,c){var d=this;return a({method:"POST",url:f+"/user/login.json",headers:{"Content-Type":"application/x-www-form-urlencoded"},transformRequest:function(a){var b=[];for(var c in a)b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")},data:{username:b,password:c}}).then(function(a){return d.drupalUser=a.user,d.drupalToken=null,d.connect()})},this.user_logout=function(){var b=this;return this.token().then(function(c){return a({method:"POST",url:f+"/user/logout.json",headers:{"X-CSRF-Token":c}}).then(function(a){return this.drupal.drupalUser=drupal_user_defaults(),this.drupal.drupalToken=null,b.connect()})})},this.user_register=function(b){return this.token().then(function(c){return a({method:"POST",url:f+"/user/register.json",headers:{"Content-Type":"application/json","X-CSRF-Token":c},data:{account:b}}).then(function(a){return a.data})})},this.comment_load=function(b){return a.get(this.restPath+"/comment/"+b+".json").then(function(a){return 200==a.status?a.data:void 0})},this.file_load=function(b){return a.get(this.restPath+"/file/"+b+".json").then(function(a){return 200==a.status?a.data:void 0})},this.node_load=function(b){return a.get(this.restPath+"/node/"+b+".json").then(function(a){return 200==a.status?a.data:void 0})},this.taxonomy_term_load=function(b){return a.get(this.restPath+"/taxonomy_term/"+b+".json").then(function(a){return 200==a.status?a.data:void 0})},this.taxonomy_vocabulary_load=function(b){return a.get(this.restPath+"/taxonomy_vocabulary/"+b+".json").then(function(a){return 200==a.status?a.data:void 0})},this.user_load=function(b){return a.get(this.restPath+"/user/"+b+".json").then(function(a){return 200==a.status?a.data:void 0})},this.comment_save=function(b){var c=null,d=null;b.cid?(c="PUT",d=this.restPath+"/comment/"+b.cid+".json"):(c="POST",d=this.restPath+"/comment.json");var e={method:c,url:d,headers:{"Content-Type":"application/json"},data:b};return this.token().then(function(b){return e.headers["X-CSRF-Token"]=b,a(e).then(function(a){return 200==a.status?a.data:void 0})})},this.file_save=function(b){var c={method:"POST",url:this.restPath+"/file.json",headers:{"Content-Type":"application/json"},data:{file:b}};return this.token().then(function(b){return c.headers["X-CSRF-Token"]=b,a(c).then(function(a){return 200==a.status?a.data:void 0})})},this.node_save=function(b){var c=null,d=null;b.nid?(c="PUT",d=this.restPath+"/node/"+b.nid+".json"):(c="POST",d=this.restPath+"/node.json");var e={method:c,url:d,headers:{"Content-Type":"application/json"},data:{node:b}};return this.token().then(function(b){return e.headers["X-CSRF-Token"]=b,a(e).then(function(a){return 200==a.status?a.data:void 0})})},this.taxonomy_term_save=function(b){var c=null,d=null;b.tid?(c="PUT",d=this.restPath+"/taxonomy_term/"+b.tid+".json"):(c="POST",d=this.restPath+"/taxonomy_term.json");var e={method:c,url:d,headers:{"Content-Type":"application/json"},data:b};return this.token().then(function(b){return e.headers["X-CSRF-Token"]=b,a(e).then(function(a){return 200==a.status?a.data:void 0})})},this.taxonomy_vocabulary_save=function(b){var c=null,d=null;b.vid?(c="PUT",d=this.restPath+"/taxonomy_vocabulary/"+b.vid+".json"):(c="POST",d=this.restPath+"/taxonomy_vocabulary.json");var e={method:c,url:d,headers:{"Content-Type":"application/json"},data:b};return this.token().then(function(b){return e.headers["X-CSRF-Token"]=b,a(e).then(function(a){return 200==a.status?a.data:void 0})})},this.user_save=function(b){var c=null,d=null;b.uid?(c="PUT",d=this.restPath+"/user/"+b.uid+".json"):(c="POST",d=this.restPath+"/user.json");var e={method:c,url:d,headers:{"Content-Type":"application/json"},data:b};return this.token().then(function(b){return e.headers["X-CSRF-Token"]=b,a(e).then(function(a){return 200==a.status?a.data:void 0})})},this.comment_delete=function(b){var c=this;return this.token().then(function(d){return a({method:"DELETE",url:c.restPath+"/comment/"+b+".json",headers:{"Content-Type":"application/json","X-CSRF-Token":d}}).then(function(a){return 200==a.status?a.data:void 0})})},this.node_delete=function(b){var c=this;return this.token().then(function(d){return a({method:"DELETE",url:c.restPath+"/node/"+b+".json",headers:{"Content-Type":"application/json","X-CSRF-Token":d}}).then(function(a){return 200==a.status?a.data:void 0})})},this.taxonomy_term_delete=function(b){var c=this;return this.token().then(function(d){return a({method:"DELETE",url:c.restPath+"/taxonomy_term/"+b+".json",headers:{"Content-Type":"application/json","X-CSRF-Token":d}}).then(function(a){return 200==a.status?a.data:void 0})})},this.taxonomy_vocabulary_delete=function(b){var c=this;return this.token().then(function(d){return a({method:"DELETE",url:c.restPath+"/taxonomy_vocabulary/"+b+".json",headers:{"Content-Type":"application/json","X-CSRF-Token":d}}).then(function(a){return 200==a.status?a.data:void 0})})},this.user_delete=function(b){var c=this;return this.token().then(function(d){return a({method:"DELETE",url:c.restPath+"/user/"+b+".json",headers:{"Content-Type":"application/json","X-CSRF-Token":d}}).then(function(a){return 200==a.status?a.data:void 0})})},this.comment_index=function(b){var c=this.restPath+"/comment.json&"+drupal_entity_index_build_query_string(b);return a.get(c).then(function(a){return 200==a.status?a.data:void 0})},this.node_index=function(b){var c=this.restPath+"/node.json&"+drupal_entity_index_build_query_string(b);return a.get(c).then(function(a){return 200==a.status?a.data:void 0})},this.taxonomy_term_index=function(b){var c=this.restPath+"/taxonomy_term.json&"+drupal_entity_index_build_query_string(b);return a.get(c).then(function(a){return 200==a.status?a.data:void 0})},this.taxonomy_vocabulary_index=function(b){var c=this.restPath+"/taxonomy_vocabulary.json&"+drupal_entity_index_build_query_string(b);return a.get(c).then(function(a){return 200==a.status?a.data:void 0})},this.user_index=function(b){var c=this.restPath+"/user.json&"+drupal_entity_index_build_query_string(b);return a.get(c).then(function(a){return 200==a.status?a.data:void 0})},this.views_json=function(b){var c=this.sitePath+"/"+b;return a.get(c).then(function(a){if(200==a.status){if(a.data.view){var b=a.data.view,c=[];return angular.forEach(a.data[b.root],function(a){var d=a[b.child];c.push(d)}),c}return a.data}})}}function drupal_entity_types(){try{return["comment","file","node","taxonomy_term","taxonomy_vocabulary","user"]}catch(a){console.log("drupal_entity_types - "+a)}}function drupal_entity_primary_key(a){try{var b=null;switch(a){case"comment":b="cid";break;case"file":b="fid";break;case"node":b="nid";break;case"taxonomy_term":b="tid";break;case"taxonomy_vocabulary":b="vid";break;case"user":b="uid";break;default:var c=a+"_primary_key";if(drupal_function_exists(c)){var d=window[c];b=d(a)}else{var e="drupal_entity_primary_key - unsupported entity type ("+a+") - to add support, declare "+c+"() and have it return the primary key column name as a string";console.log(e)}}return b}catch(f){console.log("drupal_entity_primary_key - "+f)}}function drupal_entity_primary_key_title(a){try{var b=null;switch(a){case"comment":b="subject";break;case"file":b="filename";break;case"node":b="title";break;case"taxonomy_term":b="name";break;case"taxonomy_vocabulary":b="name";break;case"user":b="name";break;default:console.log("drupal_entity_primary_key_title - unsupported entity type ("+a+")")}return b}catch(c){console.log("drupal_entity_primary_key_title - "+c)}}function drupal_function_exists(name){try{return"function"==eval("typeof "+name)}catch(error){alert("drupal_function_exists - "+error)}}function drupal_entity_index_build_query_string(a){try{var b="";if(!a)return b;if(a.fields){for(var c="",d=0;d Date: Mon, 30 Nov 2015 20:48:31 +0100 Subject: [PATCH 2/2] The module now check whether CleanURLs are enabled. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the CleanURLs module is enabled the query path string is prepended with just a forward slash “/“, otherwise it uses “/?q=“ --- README.md | 59 +++++++++++++---------------------------- angular-drupal | 40 ++++++++++++++++++++++++++++ src/angular-drupal.js | 61 +++++++++++++++++++++++++------------------ 3 files changed, 93 insertions(+), 67 deletions(-) create mode 100755 angular-drupal diff --git a/README.md b/README.md index 782268c..d7abb63 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # angular-drupal -An Angular JS module for Drupal 7 Services. +An Angular JS module for Drupal 8 RESTful Web Services. # Intro @@ -25,8 +25,7 @@ angular.module('myApp', ['angular-drupal']).run(['drupal', function(drupal) { angular.module('angular-drupal').config(function($provide) { $provide.value('drupalSettings', { - sitePath: 'http://my-drupal-site.com', - endpoint: 'api' + sitePath: 'http://my-drupal-site.com' }); }); @@ -48,52 +47,31 @@ drush dl angular_drupal drush en -y angular_drupal ``` -## 1. Drupal Services Module Setup +## 1. Drupal Setup -https://www.drupal.org/project/services +### 1.1 Enable Drupal core's "RESTful Web Services" module -``` -drush dl services -drush en -y rest_server -``` - -Then create a new endpoint by going to *admin/structure/services/add* with the -following info: +### 1.2 Install the REST UI module -``` -machine name: api -server: REST -path: api -debug: unchecked -session authentication: checked -``` +https://www.drupal.org/project/restui -Then click the edit resources link and check the box next to each resource that -should be available to your app: +Then go to "admin/config/services/rest" and enable your desired resources. We +recommend the following resources, http methods, authentications, and formats: ``` -comment -file -node -system -taxonomy_term -taxonomy_vocabulary -user +User - GET - json - cookie +User - POST - json - cookie ``` -Then click *Save*. After that, click the *Server* tab and make sure the -following boxes are checked: +### 1.3 Specify User Permissions -``` -json -application/json -application/x-www-form-urlencoded -``` - -Then click *Save*. After that flush all of Drupal's caches. +Go to admin/people/permissions and allow a user role(s) to access some of these +resources. We recommend the following (at minimum) for anonymous and +authenticated users: ``` -drush cc all +Access GET on Content resource +Access GET on User resource ``` ## 2. Angular JS Setup @@ -144,11 +122,10 @@ drupal.user_register(account).then(function(data) { ``` ### USER LOGIN +@see https://www.drupal.org/node/2403307 ``` drupal.user_login('bob', 'secret').then(function(data) { - if (data.user.uid) { - alert('Hello ' + data.user.name + '!'); - } + }); ``` diff --git a/angular-drupal b/angular-drupal new file mode 100755 index 0000000..00ff8a5 --- /dev/null +++ b/angular-drupal @@ -0,0 +1,40 @@ +#!/bin/bash + +# Globals +#APP_MODULES_DIRECTORY="app/modules" +#APP_MODULES_CUSTOM_DIRECTORY="$APP_MODULES_DIRECTORY/custom" + +function angular_drupal_install() { + cd app + mkdir bower_components + cd bower_components + mkdir angular + cd angular/ + wget https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js + mv angular.min.js angular.js + cd ../ + mkdir angular-route + cd angular-route/ + wget https://code.angularjs.org/1.4.2/angular-route.min.js + mv angular-route.min.js angular-route.js + cd ../ + mkdir angular-resource + cd angular-resource/ + wget https://code.angularjs.org/1.4.2/angular-resource.min.js + mv angular-resource.min.js angular-resource.js + cd ../ + mkdir angular-mocks + cd angular-mocks/ + wget https://code.angularjs.org/1.4.2/angular-mocks.js + cd ../ + mkdir angular-drupal + cd angular-drupal + ln -s ../../../src/angular-drupal.js angular-drupal.js +} + + +case "$1" in +install) angular_drupal_install;; +-*) usage "bad argument $1";; +esac + diff --git a/src/angular-drupal.js b/src/angular-drupal.js index a6a1ab9..0c92c4e 100644 --- a/src/angular-drupal.js +++ b/src/angular-drupal.js @@ -15,9 +15,7 @@ function drupal($http, $q, drupalSettings, drupalToken) { // GLOBALS var url_prepend = '/?q='; var sitePath = drupalSettings.sitePath; - var restPath = sitePath + '/?q=' + drupalSettings.endpoint; - this.sitePath = sitePath; - this.restPath = restPath; + var restPath = sitePath; // Check if CleanURLs are enabled. var xmlhttp; @@ -78,7 +76,11 @@ function drupal($http, $q, drupalSettings, drupalToken) { }, 100); }); } +<<<<<<< HEAD return $http.get(sitePath + + url_prepend + 'services/session/token').then(function(result) { +======= + return $http.get(restPath + '/rest/session/token').then(function(result) { +>>>>>>> easystreet3/8.x-1.x if (result.status == 200) { drupalToken = result.data; //console.log('grabbed token from server: ' + drupalToken); @@ -93,14 +95,22 @@ function drupal($http, $q, drupalSettings, drupalToken) { this.token : this.drupal.token; return _token_fn().then(function(token) { return $http({ - method: 'POST', - url: restPath + '/system/connect.json', - headers: { 'X-CSRF-Token': token } + method: 'GET', + url: restPath + '/drupalgap/system/connect?_format=json', + /*headers: { 'X-CSRF-Token': token }*/ }).then(function(result) { if (result.status == 200) { return result.data; } }); }); }; + /*this.connect = function() { + var deferred = $q.defer(); + setTimeout(function() { + deferred.notify('About to greet '); + deferred.resolve('Hello, '); + }, 100); + return deferred.promise; + };*/ // USER LOGIN this.user_login = function(username, password) { @@ -113,8 +123,12 @@ function drupal($http, $q, drupalSettings, drupalToken) { var drupal = this; return $http({ method: 'POST', - url: restPath + '/user/login.json', - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + url: restPath + '/user/login', + /*url: restPath + '/user/login?' + + 'name=' + encodeURIComponent(username) + '&pass=' + encodeURIComponent(password) + '&form_id=user_login_form',*/ + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + }, transformRequest: function(obj) { var str = []; for (var p in obj) @@ -122,33 +136,28 @@ function drupal($http, $q, drupalSettings, drupalToken) { return str.join('&'); }, data: { - username: username, - password: password + name: username, + pass: password, + form_id: 'user_login_form', + _format: 'json' } }).then(function(result) { - drupal.drupalUser = result.user; + console.log(result); + /*drupal.drupalUser = result.user; drupal.drupalToken = null; - return drupal.connect(); + return drupal.connect();*/ }); }; // USER LOGOUT this.user_logout = function() { - var drupal = this; - return this.token().then(function(token) { - return $http({ - method: 'POST', - url: restPath + '/user/logout.json', - headers: { 'X-CSRF-Token': token } - }).then(function(result) { - /*if (typeof drupalToken !== 'undefined') { - drupalToken = null; - }*/ - this.drupal.drupalUser = drupal_user_defaults(); - this.drupal.drupalToken = null; - return drupal.connect(); - }); + return $http({ + method: 'GET', + url: restPath + '/user/logout' + }).then(function(result) { + drupal.drupalUser = drupal_user_defaults(); + drupal.drupalToken = null; }); };