xDaizu
xDaizu

Reputation: 1061

Calling Moodle web service using Unirest

I want to communicate with an installation of Moodle 2.9.

The following sample client is a slight modification of: https://github.com/moodlehq/sample-ws-clients/blob/master/PHP-REST/client.php to use Unirest instead of Curl and JSON instead of XML:

        $token = 'd1c74d6466daaaaad59b5d99906bfc84';
        $domainname = 'http://moodle.example.com';
        $functionname = 'core_user_create_users';
        // REST RETURNED VALUES FORMAT
        $restformat = 'json'; 

        $user1 = new \stdClass();
        $user1->username = 'testusername1';
        $user1->password = 'testpassword1';
        $user1->firstname = 'testfirstname1';
        $user1->lastname = 'testlastname1';
        $user1->email = '[email protected]';
        $user1->auth = 'manual';
        $user1->idnumber = 'testidnumber1';
        $user1->lang = 'en';
        $user1->theme = 'standard';
        $user1->timezone = '-12.5';
        $user1->mailformat = 0;
        $user1->description = 'Hello World!';
        $user1->city = 'testcity1';
        $user1->country = 'au';
        $preferencename1 = 'preference1';
        $preferencename2 = 'preference2';
        $user1->preferences = array(
            array('type' => $preferencename1, 'value' => 'preferencevalue1'),
            array('type' => $preferencename2, 'value' => 'preferencevalue2'));

        $user2 = new \stdClass();
        $user2->username = 'testusername2';
        $user2->password = 'testpassword2';
        $user2->firstname = 'testfirstname2';
        $user2->lastname = 'testlastname2';
        $user2->email = '[email protected]';
        $user2->timezone = 'Pacific/Port_Moresby';
        $users = array($user1, $user2);
        $params = array('users' => $users);
        /// REST CALL

        $serverurl = $domainname . '/webservice/rest/server.php' . '?wstoken=' . $token . '&wsfunction=' . $functionname;

        //if rest format == 'xml', then we do not add the param for backward compatibility with Moodle < 2.2
        $restformat = ($restformat == 'json') ? '&moodlewsrestformat=' . $restformat : '';
        $headers = array('Accept' => 'application/json');
        $response = UnirestRequest::post($serverurl . $restformat, $headers, json_encode($params));

On execution I got an error:

"Notice: Array to string conversion"

, allegedly because of the parameters going in the body. So, I figured I had to serialize the body before sending it, but when I tried:

$response = UnirestRequest::post($serverurl . $restformat, $headers, json_encode($params));

I got back from Moodle:

{"exception":"invalid_parameter_exception","errorcode":"invalidparameter","message":"Detectado valor de par\u00e1metro no v\u00e1lido","debuginfo":"Missing required key in single structure: users"} ◀"

There must be something I'm not understanding about how exactly the POST request must look like. Any suggestion?

Upvotes: 0

Views: 451

Answers (1)

Kisaragi
Kisaragi

Reputation: 2218

Moodle expects the body of the post to be URL encoded, so your body must be built using http_build_query($params) (or any other method to encode your data) such as:

 $convertedpostdata = implode('&', $params);//where $params is  an array

As far as why, I dont really recall, I remember struggling with an implementation a while ago, you can view [your_moodle_installation.com]/admin/webservice/documentation.php for more documentation, additionally you here's an example of what I did:

https://gist.github.com/Scott972/5d9e9495c1397a2ad728b66288ce1d42

Upvotes: 1

Related Questions