Giter Site home page Giter Site logo

drupal-client's Introduction

drupal-client

A Javascript client for Drupal 7 / Services Module

Build Status

Requirements

  1. An installation of Drupal 7.x and Services Module

  2. REST Server module enabled, an endpoint defined and appropriate permissions (system, user, node, etc.). In server settings, enable only response formatter json the request parsing mime types application/json, application/x-www-form-urlencoded and multipart/form-data.

  3. A Javascript project - node.js or Titanium are known to work.

Installation

browser

bower install drupal-client

<script src="bower_components/drupal-client/build/drupal.min.js"></script>

node.js

npm install drupal-client

var Drupal = require('drupal');

Titanium/Alloy

Copy lib/drupal.js and lib/field.js into your app/lib/ folder.

var Drupal = require('drupal');

Usage

Configure the client for your installation of Drupal+Services. Note that the URL includes the trailing slash.

var drupal = new Drupal();

drupal.setRestPath("http://mywebsite.com/", "rest_endpoint");

Create a Service and enable (at least) the Resources called "system" and "user".

Get a session

drupal.systemConnect(
	//success
	function(sessionData) {
		var uid = sessionData.user.uid;
		console.log('session found for user '+uid);
	},
	//failure
	function(error) {
		console.log('boo :(');
	}
);

Create an account

var user = {
	name: 'my_new_username',
	pass: 'my_new_password',
	mail: '[email protected]'
};

drupal.createAccount(user,
	//success
	function(userData) {
		console.log('yay!');
	},
	//failure
	function(error) {
		console.log('boo :(');
	},
	headers //optional
);

Login

var my_username = "<DRUPAL USERNAME>";
var my_password = "<DRUPAL PASSWORD>";

var userObject;

drupal.login(my_username, my_password,
	function(userData) {
		console.log('User ' + userData.uid + ' has logged in.');
		userObject = userData;
	},
	function(err){
		console.log('login failed.');
	}
);

Modify User Info

This updates an account profile on the server. userObject is a user object that may have been received from a login request (see above).

drupal.putResource("user/"+userObject.uid, userObject,
	function(userData) {
		console.log('user has been updated.');
	},
	function(err){
		console.log('user update failed.');
	}
);

Upload A File

var filename = "uploaded_file.png";
var data = require('fs').readFileSync("path/to/file/file.png");
var base64data = data.toString('base64');
var filesize = data.length;

drupal.uploadFile(base64data, filename, filesize,
  function (response) {
    fid = response.fid;
  },
  function (err) {
    console.log(err);
  },
  function (progress_event) {
    console.log(progress_event.loaded + '/' + filesize + ' uploaded');
  }
);

Create a New Node

var node = {
  type: "my_content_type",
  title: "My New Node",
  body: drupal.field.structureField("Check out this great new node!"),
  field_bool: drupal.field.structureField(1),
  field_decimal: drupal.field.structureField(.1),
  field_float: drupal.field.structureField(2.3),
  field_integer: drupal.field.structureField(4),
  field_multiple: drupal.field.structureField(["one", "two", "three"]),
  field_file: drupal.field.structureField(fid, "fid"),
  field_date: field.structureField(new Date())
};

drupal.createNode(node,
  function (resp) {
    console.log(resp);
  },
  function (err) {
    console.log(err);
  }
);

Make Requests

The workhorse function of the interface is makeAuthenticatedRequest(config, success, failure, headers). There are a few helper functions included for posting/getting nodes, getting views, uploading files, etc. They all construct a call to makeAuthenticatedRequest(). This function should facilitate most things that people want to do with Drupal in a mobile environment. It's also easy to use `makeAuthenticatedRequest' to make requests against custom Services. The short-term roadmap includes calls to the services supporting entities.

Tests

To run the tests, rename test/config.js.example to test/config.js and replace strings with the url of your Drupal install and your service endpoint.

npm install

npm test

drupal-client's People

Contributors

bob-sims avatar jbeuckm avatar muhammadreda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

drupal-client's Issues

Add fs module for file upload

Hi Joe,
When I add require('fs') I get this error :
[ERROR] : Script Error Couldn't find module: fs
Can you help me :)
Tks,

Error that rest return

Hi,

How can I return message that services return instead of :

[INFO] : registerNewUser FAIL
[INFO] : {
[INFO] : code = 406;
[INFO] : error = "HTTP error";
[INFO] : source = "[object TiNetworkHTTPClient]";
[INFO] : success = 0;
[INFO] : type = error;
[INFO] : }

Titanium config

Hi,

Where I have to put this variables to configure my Titanium App :

var drupal = require('drupal');
drupal.setRestPath("http://mywebsite.com/", "rest_endpoint");

Tks,

getCsrfToken does not correctly detect empty X-CSRF-Token

existingToken can be a string 'null' (not empty). Therefore, the if (existingToken) statement is evaluated as true when existingToken is a string 'null'. A possible fix is changing the if statement to
if ((existingToken) && ('null' != existingToken)).

Inside browser, I am always getting POST http://mysite.com/server/system/connect 401 (Unauthorized: CSRF validation failed)

Hello,
I am trying the sample code in a browser, and always getting: CSRF validation failed.

        var drupal = new Drupal();
        drupal.setRestPath("http://mysite.com/", "server");

        drupal.systemConnect(
        //success
        function(sessionData) {
            var uid = sessionData.user.uid;
            console.log('session found for user '+uid);
        },
        //failure
        function(error) {
            console.log(error);
        }
        );

I also tried
drupal.getCsrfToken (
function(e) {
console.log(e);
});

and I am getting a valid CSRF token. Any tips why this is failing?

Checkbox fields are not updating

Hello Joe,

Great to see that you continue to work on this project. ive picked up working on the documentation and the app again so i thought id report this issue here. im using services 3.7 but this shouldnt have an impact on the checkboxes, no?

its primarily about checkboxes (on user profile) that are not being updated (or set to "0" in the example). the decimal and text fields are correctly updated when passing the object to the drupal.putResource function.

var object = {
    field_smilies: drupal.field.structureField("666"), // --> DECIMAL FIELD WORKS
    field_city: drupal.field.structureField("test666"), // --> TEXT FIELD WORKS
    //CHECKBOXES --> CANT GET THEM TO WORK      
    field_serious: drupal.field.structureField(0), // DOESNT SET field_serious (machine name) TO false or 0 on profile, but "user has been updated."shows up in console
    field_serious1: drupal.field.structureField(0),
};

Ive attached a screenshot as well showing details about this (taxonomy terms are not mentioned in the README file, so i guess you are aware of that). ive tried all widgets for taxonomy terms (also autocomplete doesnt work, this works with an organic group reference field though).

profile update

cheerios,

Strange, User can't login

Hi,

I create user with this code the registration is Ok and I found activated user in Drupal but can't login with this user !!!

var user = {
name: 'my_new_username',
pass: 'my_new_password',
mail: '[email protected]'
};

drupal.createAccount(user,
//success
function(userData) {
console.log('yay!');
},
//failure
function(error) {
console.log('boo :(');
}
);

passing object to postResource function

im trying to add voting feature to the app. there is already the drupal voting_api services module. the set_votes and select_votes resources are available and show up in services. so from the drupal side it should work.

here is some info on the object that needs to be passed to services to set a vote (https://drupal.org/node/2145873)

{
"votes": [
{
entity_id: 2,
value_type: "points",
tag: "vote",
value: 11
}
]
}

any suggestion how i can pass this voting object to the drupal.postResources function and make it work is highly appreciated. :)

function vote (){
var resourceName = "votingapi/set_votes";
drupal.postResource(resourceName, function(object){
var object = {"votes":
[{
entity_id: 2,
value_type: "percent",
tag: "vote",
value: 10
}]
}, function (response) {
alert("working");
},
function (error) {
alert (error + "error vote function");
}
);
}

Session/Token expiration when user has not logged in for weeks

what is the best way to handle the case when a user has not logged in for - say - 4 weeks? sessions and token have expired by then.

regarding the sessions, in the settings file there are those values (from https://www.drupal.org/node/590832)

ini_set('session.cache_expire', 2000000);
ini_set('session.cache_limiter', 'none');
ini_set('session.cookie_lifetime', 2000000);
ini_set('session.gc_maxlifetime', 2000000);

apart from increasing those values in the settings file, any suggestion how to implement a fool-proof and performant login mechanism? some thoughts on the general implementation are appreciated!

Authentication window keeps popping up

Hi, I keep getting an authentication popup window, if user is already logged on or passing wrong user details.

screen shot 2015-09-08 at 11 23 04

If i click cancel i get: Failed to load resource: the server responded with a status of 401 (Unauthorized : CSRF validation failed)

If i click cancel on wrong credentials it console logs after i click cancel, meaning i can't show users its a wrong username or password.

My Drupal site is located in a subfolder, while the site is created with Angular as frontend.

Accessing values from a Drupal view

hello Joe,

I’ve finally figured out how the calling and library functions play together. yay!! the response and error arguments gave me quite some headache. im writing a more detailed explanation next week where i include examples like get a node, vote (via POST) and retrieve a view.

regarding the views, im having an issue with accessing the individual values/fields from a view (the data shows up in the console log though).

I can retrieve the data from the view and it shows up in the console log (see screenshot views where it outputs the image, nid and title from the view), but i cannot access the individual values with response.nid for instance. it says its undefined.

views

node works:

when i retrieve a node i can access the values with response.body.und[0].value for instance (see screenshot node)

node

but when i try response.nid in the get_view function, it doesn’t work.

i noted that when im pulling a VIEW, the console outputs the json objects encapsulated with ROUND brackets whereas when i pull a NODE (where i can access the individual values), there are CURLY brackets.

any ideas why i can’t access the individual values?

Image upload

hello,

the titanium app should allow user to upload an image to his user profile. anyone has this feature working (as there is a comment in the library saying that it has not been tested for a while)?

i get a success rest response ("file" is empty though and filesize is only 25 bytes) but no image has been uploaded

{"fid":"113","uid":"1","filename":"photo.jpg","uri":"s3://photo_2.jpg","filemime":"image/jpeg","filesize":"25","status":"1","timestamp":"1420912934","rdf_mapping":[],"uri_full":"//bucketagain7778.s3.amazonaws.com/photo_2.jpg","target_uri":"photo_2.jpg","file":"","image_styles":[]}

profile.js code

function upload(event){
    var photo = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, "photo.jpg");
    photo.write(event.media);
    setTimeout(function(){
        //photo.read();
        console.log(JSON.stringify(photo) + "this is stringed photo object");           
        console.log("Photo.size: " + photo.size);
        console.log("photo.nativePath: " + photo.nativePath);
        console.log("photo.name: "+ photo.name);
        console.log("photo.extension: " + photo.extension); // outputs  [object TiFilesystemFile]this is photo extension[object TiFilesystemFile]this is photo extension

        var base64data = Ti.Utils.base64encode(photo.toString());
        //var base64data = photo.toString('base64');
        var filename = photo.name;
        var filesize = photo.size;
        console.log("filename: " + filename);
        console.log("base64data: " + base64data);
        console.log("filesize: " + filesize);

        drupal.uploadFile(base64data, filename, filesize,
        function (response) {
         fid = response.fid;
         console.log(JSON.stringify(response) +  " this is response");
         },
          function (err) {
            console.log(err);
          },
          function (progress_event) {
            console.log(progress_event.loaded + '/' + filesize + ' uploaded');
          }
        );

    },200);

console:

[INFO] :   Photo.size: 931061
[INFO] :   photo.nativePath: file:///Users/macmini/Library/Developer/CoreSimulator/Devices/5ACEEA5A-F4FF-4A1A-AE59-2D822C19EB58/data/Containers/Data/Application/0B5371B0-90B4-45C0-9859-64A3B1E5ECB5/Documents/photo.jpg
[INFO] :   photo.name: photo.jpg
[INFO] :   photo.extension: [object TiFilesystemFile]
[INFO] :   filename: photo.jpg
[INFO] :   base64data: W29iamVjdCBUaUZpbGVzeXN0ZW1GaWxlXQ==
[INFO] :   filesize: 931061

systemConnect error should not delete drupal cookie and csrf token

I'm using this in an app. If the app attempts to run systemConnect and for some reason get an error the code currently is set to delete the cookies, thus wiping out an otherwise valid session. The next time that systemConnect runs the user is effectively logged out.

Thanks for your hard work on this.

xhr.onerror = function (e) {
        console.log("There was an error calling systemConnect: ");
        console.log(e);

        // since systemConnect failed, will need a new csrf and session
        Settings.setString(self.settingsPrefix + "X-CSRF-Token", null);
        Settings.setString(self.settingsPrefix + "Drupal-Cookie", null);

        failure(e);
    };

P.S. the 'null token' issue mentioned in another bug report is in the same function

Drupal.prototype.systemConnect = function (success, failure) {

    var self = this;

    // if session exists, token will be required
    var token = Settings.getString(this.settingsPrefix + "X-CSRF-Token");

    if (!token || token == "null" || token.length < 10) {
        console.log("will request token before systemConnect");
        self.getCsrfToken(
            function () {
                self.systemConnect(success, failure);
            },
            function (err) {
                failure(err);
            }
        );
        return false;
    } else {
        console.log("will systemConnect with token "+token);
    }

SMTP Parse Error when registering user with non-existent email

When using the drupal smtp module, i always got a parse error when i registered a new user with an email that did not exist. the account was created, but the error message was always visible on the device and the simulator.

the responseText from the SMTP module looks like this:

SMTP Error: The following recipients failed: [email protected]\n{"uid":"99","uri":"http://carmaba.rhcloud.com/rest/v1/user/99"}

some hacky fix in the makeRequest function (from lines 296):

xhr.onload = function () {

    if (xhr.status === 200) {
        // console.log("xhr.responseText " + xhr.responseText);
        if (xhr.responseText.lastIndexOf("SMTP Error",0) === 0) {
            success(responseData);
        } else {
            var responseData = JSON.parse(xhr.responseText);
            success(responseData);
        }
    } else {
        console.log('makeRequest returned with status ' + xhr.status);
        failure(xhr.responseText);
    }
};

error on node creation

Hi,

I have an error on node creation :

[INFO] : {"type":"error","source":{"method":"POST","url":"http://website/api/rest/node.json","ondatastream":null},"code":406,"error":"HTTP error","success":false}
[INFO] : FAILED REQUEST:
[INFO] : makeRequest()
[INFO] : POST http://website/api/rest/node.json
[INFO] : Cookie: SESSd666c81090e6f08758b98b1d618fe488=VmeFuXcn-KpEnq2PcsKDStRpe75yiWxRKR0YCEVR2AI
[INFO] : X-CSRF-Token: ueeR5zJ82wMORfQ8RaJfu5OlkKXfauV8eUtRH86zq5M
[INFO] : {"type":"article","title":"test node title"}
[ERROR] : {
[ERROR] : code = 406;
[ERROR] : error = "HTTP error";
[ERROR] : source = "[object TiNetworkHTTPClient]";
[ERROR] : success = 0;
[ERROR] : type = error;
[ERROR] : }

Tks,

login

hello Joe,

Im making progress with the drupal app that uses your great drupal-client library. the documentation is onhold until i figured out how to use the library in a good way - but its going well. :)

one issue im having is with newly users (admin2 in the login screenshot) that have been registered through the app. i cant login with their credentials (neither through the app nor through the drupal site) after their accounts have been created - i noticed that the X-CSFR-token is "NULL".

can you confirm that this works (registration via the app and then subsequent login)? as the whole thing is quite complex, it might well be a configuration issue.

when i set the password of user "admin2" manually (after registration via the app) in the drupal backend i can login with this account as well.

login

.

Logout error

I have a few days with Drupal Services and Titanium, today I found this library, for now all work perfect, I can login and get a view restricted to authenticated users, but I can't logout, after trial and error I found that the logout method need

contentType: "application/json"

Passing arguments to getView function

hello Joe,

Going really well here - just experimenting with a simple messaging functionality with OG and views.

i dont know if this is a bug or not, but i thought id post it here.

i have a view that im passing arguments to and the working and correct link is: http://drupal2-testdrupal.rhcloud.com/restapi/views/chats_details?args=27

correct

when i pass the arguments from the calling function of the app like this:

var viewName = "chats_details";
var args = [27];
var headers = "";

drupal.getView_custom(viewName, args, function(response){
Ti.API.info(JSON.stringify(response) + " this is from within the calling function");
}, function (error)
{ Ti.API.info(JSON.stringify(error) + " this is error message from the calling function");},
headers);
});

to the getView library function

function getView_custom(viewName, args, success, failure, headers) {
makeAuthenticatedRequest({
servicePath:"views/" + viewName + ".json?" + encodeUrlString(args),
httpMethod:'GET',
contentType:"application/json"

}, function(response) {
    success(response);
    //Ti.API.info(response + " this is response from within the lib function");     
    }, function(error){
    failure(response);
    }, headers);

}

the output views array is empty. see the message log screenshots which shows http://drupal2-testdrupal.rhcloud.com/restapi/views/chats_details.json?0=27 as location (0 instead of the term "args").

message_log

i am using now a slightly modfified version of the getView function in the library to so that the service path looks like "servicePath:"views/" + viewName + ".json?args=" + args," and this works and the correct view shows up.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.