I'm implementing a moodle web service on localhost.
I followed all the steps to register the service, and I have the token to make the corresponding calls.
I have used the template for REST PHP by Jerome Mouneyrac (https://github.com/moodlehq/sample-ws-clients/blob/master/PHP-REST/client.php).
My code:
$token = '60d4aef82f787b7a0c8499a648a6a919';
$domainname = 'http://localhost/moodle';
$functionname = 'core_user_create_users';
$restformat = 'json';
$user1 = new stdClass();
$user1->username = 'testo';
$user1->password = 'Password_2015';
$user1->createpassword = 0;
$user1->firstname = 'testfirstname1';
$user1->lastname = 'testlastname1';
$user1->email = 'muletssss#gmail.com';
$user1->auth = 'manual';
$user1->idnumber = '';//'testidnumber1';
$user1->lang = 'es';
$user1->theme = "standard";
$user1->timezone = '-12.5';
$user1->mailformat = 0;
$user1->description = 'Hello World!';
$user1->city = 'testcity1';
$user1->country = 'au';
$users = array($user1);//, $user2);
$params = array('users' => $users);
$serverurl = $domainname . '/webservice/rest/server.php'. '?wstoken=' . $token . '&wsfunction='.$functionname;
require_once('./curl.php');
$curl = new curl;
$restformat = ($restformat == 'json')?'&moodlewsrestformat=' . $restformat:'';
$resp = $curl->post($serverurl . $restformat, $params);
print_r($resp);
If I execute it returns this response
{"exception":"invalid_parameter_exception","errorcode":"invalidparameter","message":"Detectado valor de par\u00e1metro no v\u00e1lido","debuginfo":"users => Detectado valor de par\u00e1metro no v\u00e1lido: theme => Detectado valor de par\u00e1metro no v\u00e1lido: Invalid external api parameter: the value is \"standard\", the server was expecting \"theme\" type"}
The API documentation says that the value is string and standard default, so I comment this line because it is optional. And returns
{"exception":"moodle_exception","errorcode":"forcepasswordchangenotice","message":"error\/forcepasswordchangenotice"}
Does anyone know what I can do to work correctly, any solution?
I was facing a similar issue, I have solved it. The issue was that the user that I was using for the web services had force password reset checked while creation. I had not logged in once the user was created and was only using it for the Webservice. Hence I was this error was showing up. I unchecked force password reset from my admin account and it was solved.
Related
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 = 'testemail1#moodle.com';
$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 = 'testemail2#moodle.com';
$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?
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
I'm trying to add new users to moodle 3.2 using a REST web service, and i want to customize thees fields (phone1, department, institution) in the student profile.
I used this code
$token = 'a38805c00f33023f7854d5adc720c7a7';
$domainname = 'http://localhost/moodle';
$functionname = 'core_user_create_users';
$restformat = 'json';
$user2 = new stdClass();
$user2->username = strtolower( $rsnew['Serial']);
$user2->password = $rsnew['pass'];
$user2->firstname = $rsnew['Fname'];
$user2->lastname = $rsnew['Lname'];
$user2->email = $rsnew['Email'];
$user2->lang = 'en';
$user2->auth = 'manual';
$user2->country = $rsnew['Country'];
$user2->timezone = '99';
$user2->phone1 = $rsnew['phone'];
$user2->department = $rsnew['dept'];
$user2->institution = $rsnew['branch'];
$user2->idnumber = $rsnew['grade'];
$users = array($user2);
$params = array('users' => $users);
$serverurl = $domainname . '/webservice/rest/server.php'. '?wstoken=' . $token . '&wsfunction='.$functionname;
require_once('./curl.php');
$curl = new curl;
$restformat = ($restformat == 'json')?'&moodlewsrestformat=' . $restformat:'';
$resp = $curl->post($serverurl . $restformat, $params);
But i get this error :
{
"exception": "invalid_parameter_exception",
"errorcode": "invalidparameter",
"message": "Invalid parameter value detected",
"debuginfo": "users => Invalid parameter value detected: Unexpected keys (phone1, department, institution) detected in parameter array."
}
What should I do to fix that?
Just as the error suggests, that web service does not support the fields you are giving it. You can refer to the function itself to find out what fields are supported and what data they must contain.
core_user_get_users
I am not aware of a workaround for your problem using existing web services. However, you can create your own which includes those additional fields.
Note that this sounds to me like this is a desirable feature and should be raised on the issue tracker.
Using the default Tumblr v2 API, I'm able to connect to my application, and retrieve posts from my own account. However, I'd like users to be able to connect their own accounts. I've tried to figure this out but I'm not entirely sure how to use OAuth (im using this class). How is this done?
The code I'm using to retrieve dashboard posts is:
$consumerKey = 'xxx';
$consumerSecret = 'xxx';
$tumblr = new Tumblr\API\Client(
$consumerKey,
$consumerSecret
);
var_dump( $tumblr->getDashboardPosts() ); // using var_dump for testing purposes only
This code works, but it's only returning the code for my PERSONAL account.
I figured it out, thanks to Github user seejohnrun.
require_once 'include/util.php';
$consumerKey = 'XXX';
$consumerSecret = 'XXX';
$client = new Tumblr\API\Client($consumerKey, $consumerSecret);
$requestHandler = $client->getRequestHandler();
$requestHandler->setBaseUrl('https://www.tumblr.com/');
// If we are visiting the first time
if (!$_GET['oauth_verifier']) {
// grab the oauth token
$resp = $requestHandler->request('POST', 'oauth/request_token', array());
$out = $result = $resp->body;
$data = array();
parse_str($out, $data);
// tell the user where to go
echo ' GO ';
$_SESSION['t']=$data['oauth_token'];
$_SESSION['s']=$data['oauth_token_secret'];
} else {
$verifier = $_GET['oauth_verifier'];
// use the stored tokens
$client->setToken($_SESSION['t'], $_SESSION['s']);
// to grab the access tokens
$resp = $requestHandler->request('POST', 'oauth/access_token', array('oauth_verifier' => $verifier));
$out = $result = $resp->body;
$data = array();
parse_str($out, $data);
// and print out our new keys we got back
$token = $data['oauth_token'];
$secret = $data['oauth_token_secret'];
echo "token: " . $token . "<br/>secret: " . $secret;
// and prove we're in the money
$client = new Tumblr\API\Client($consumerKey, $consumerSecret, $token, $secret);
$info = $client->getUserInfo();
echo "<br/><br/>congrats " . $info->user->name . "!";
}
I am new to Moodle. I have done creating user by using web service api and that is running successfully. Now I want to create a course same way. I am using 'core_course_create_courses' function to do this. The post body of my request is
$courses=array("courses" =>
array(
0=>array(
"fullname" => $fullname,
"shortname" => $shortname,
"categoryid" => $categoryid,
"idnumber" =>$idnumber,
"summary"=>$summary,
"summaryformat"=>$summaryformat
)
)
);
Whenever I am running this it is giving me response "{\"exception\":\"moodle_exception\",\"errorcode\":\"errorcatcontextnotvalid\",\"message\":\"You cannot execute functions in the category context (category id:101). The context error message was: Invalid parameter value detected\"}".
But the course category 'programming' with id 101 exists in my moodle site. Please help me. Thanks in advance.
I was wrong ,the categoryid is not the id of the category,it is the sequence id of the category.Now if I give 2 ,it works fine.
$token = $this->config->item('id_token');
$domainname = $this->config->item('domainname');
$functionname = 'core_course_create_courses';
$restformat = 'json';
//crear objeto de acuerdo a la estructura para crear Categoría en Moodle
$curso = new stdClass();
$curso->fullname = $data['patron']['nombre'];
$curso->shortname = $data['patron']['nombre']; // Is unique
**$curso->idnumber = $id; // consecutive
$curso->visible = 1;
$curso->categoryid = 6;
$modulos = array($curso);
$params = array('courses' => $modulos);
header('Content-Type: text/plain');
$serverurl = $domainname . '/webservice/rest/server.php' . '?wstoken=' . $token . '&wsfunction=' . $functionname;
require_once(APPPATH . 'libraries/curl.php');
$curl = new curl;
$restformat = ($restformat == 'json') ? '&moodlewsrestformat=' . $restformat : '';
$resp = $curl->post($serverurl . $restformat, $params);
return $resp;
I've had the client approve my user as an administrator after I created my application through LinkedIn's Developer backend. I even had the client create their OWN application and provide me the client keys for it, however I'm getting the same error message every time when trying to pull the company updates:
"Member 0 does not have permission to get company 1311XXX"
Here's my code for that page:
$config['base_url'] = 'http://www.hiddenlink.com/resources/li-oauth-src/auth.php';
$config['callback_url'] = 'http://www.hiddenlink.com/resources/li-oauth-src/demo.php';
$config['linkedin_access'] = '770lXXXXXXXXXX';
$config['linkedin_secret'] = 'hcxpOtXXXXXXXXXX';
include_once "linkedin.php";
# First step is to initialize with your consumer key and secret. We'll use an out-of-band oauth_callback
$linkedin = new LinkedIn($config['linkedin_access'], $config['linkedin_secret'], $config['callback_url'] );
//$linkedin->debug = true;
if (isset($_REQUEST['oauth_verifier'])){
$_SESSION['oauth_verifier'] = $_REQUEST['oauth_verifier'];
$linkedin->request_token = unserialize($_SESSION['requestToken']);
$linkedin->oauth_verifier = $_SESSION['oauth_verifier'];
$linkedin->getAccessToken($_REQUEST['oauth_verifier']);
$_SESSION['oauth_access_token'] = serialize($linkedin->access_token);
header("Location: " . $config['callback_url']);
exit;
}
else{
$linkedin->request_token = unserialize($_SESSION['requestToken']);
$linkedin->oauth_verifier = $_SESSION['oauth_verifier'];
$linkedin->access_token = unserialize($_SESSION['oauth_access_token']);
}
$json_response = $linkedin->getCompanyUpdates("1311XXX");
$json = json_decode($json_response);
echo "<pre>";
print_r($json);
echo "</pre>";
for($x = 0; $x < 2; $x++){
$json_value = $json->values[$x];
$articleURL = $json_value->updateContent->companyStatusUpdate->share->content->eyebrowUrl;
$postTitle = $json_value->updateContent->companyStatusUpdate->share->content->title;
$description = htmlspecialchars($json_value->updateContent->companyStatusUpdate->share->content->description);
$timestamp = $json_value->updateContent->companyStatusUpdate->share->timestamp;
echo '<pre>';
print_r($description);
echo '<br />';
print_r($articleURL);
echo '<br />';
print_r($postTitle);
print_r(date("jS M, Y", $timestamp));
echo '</pre>';
}
Here is the code for the getCompanyUpdates function being called for the json_response variable:
function getCompanyUpdates($id){
$updateURL = $this->base_url . "/v1/companies/" . $id . "/updates?format=json";
$request = OAuthRequest::from_consumer_and_token($this->consumer, $this->access_token, "GET", $updateURL);
$request->sign_request($this->signature_method, $this->consumer, $this->access_token);
$auth_header = $request->to_header("https://api.linkedin.com"); # this is the realm
$response = $this->httpRequest($updateURL, $auth_header, "GET");
return $response;
}
I have zero clue what I'm doing wrong, but it's clear I'm doing something wrong. Any help would be much appreciated
You don't seem to be explicitly passing a scope value anywhere in your oauth workflow, so I can only presume you are relying on your LinkedIn application's default scope values to be configured correctly.
Check to make sure you are requesting the rw_company_admin member permission when attempting to make that API call.