Am I calling core_role_assign_roles correctly? What do these errors mean?

Am I calling core_role_assign_roles correctly? What do these errors mean?

by Jocelyn Ireson-Paine -
Number of replies: 6

On Moodle 2.2, I'm trying to call core_role_assign_roles, but I'm getting errors that I don't understand. I created a user with the program I'd posted at http://moodle.org/mod/forum/discuss.php?d=193295#p841702 , "Example of using Web services". I then tried to assign it the Teacher role in context System by running the code below:

  $token = 'af8fe44eggs1and1ham743779a2501';

  $domain = 'http://moodle.ireson-paine.com';

  $role_id = 3;    // Teacher.
  $context_id = 1; // System.
  $user_id = 134;  // An existing user.

  $function = 'core_role_assign_roles';

  $serverurl = $domain . '/webservice/rest/server.php'. '?wstoken=' . $token . '&wsfunction='.$function;
  require_once( './curl.php' );
  $curl = new curl;

  $assignment = array( 'roleid' => $role_id, 'userid' => $user_id, 'contextid' => $context_id );
  $assignments = array( $assignment );
  $params = array( 'assignments' => $assignments );

  $response = $curl->post( $serverurl . $restformat, $params );

  print "Response = " . $response;

This gave me the following XML response:

  <?xml version="1.0" encoding="UTF-8" ?>   
  <EXCEPTION class="invalid_parameter_exception">   
  <MESSAGE>Invalid parameter value detected
  </MESSAGE>   
  <DEBUGINFO>Can not assign roleid=3 in contextid=1
  </DEBUGINFO>   
  </EXCEPTION>

I don't understand that. Is it because the user needs some capability that it lacks, or what? A bit more explanation about why Moodle can't do the assignment would be really helpful.

In an attempt to find out, I then wrote a program that looped over all role and context IDs between 0 and 50, assigning them to the same user and reporting the responses. I found that none of the calls succeeded, and that I got the following five kinds of error:

  (1)
  <EXCEPTION class="coding_exception">
  <MESSAGE>Coding error detected, it must be fixed by a programmer:
           Invalid context id specified context::instance_by_id()</MESSAGE>
  </EXCEPTION>

  (2)
  <EXCEPTION class="coding_exception">
  <MESSAGE>Coding error detected, it must be fixed by a programmer: PHP catchable fatal error</MESSAGE>
  <DEBUGINFO>Argument 1 passed to external_api::clean_returnvalue() must be 
             an instance of external_description, null given, called in 
             /var/www/moodle/moodle/webservice/rest/locallib.php on line 88 and defined</DEBUGINFO>
  </EXCEPTION>

  (3)
  <EXCEPTION class="invalid_parameter_exception">
  <MESSAGE>Invalid parameter value detected</MESSAGE>
  <DEBUGINFO>Can not assign roleid=1 in contextid=4</DEBUGINFO>
  </EXCEPTION>

  (4)
  <EXCEPTION class="require_login_exception">
  <MESSAGE>Course or activity not accessible.</MESSAGE>
  <DEBUGINFO>Not enrolled</DEBUGINFO>
  </EXCEPTION>

  (5)
  <EXCEPTION class="invalid_parameter_exception">
  <MESSAGE>Invalid parameter value detected</MESSAGE>
  <DEBUGINFO>Context does not exist</DEBUGINFO>
  </EXCEPTION>

Error 1, I think I understand. It happened when the context ID was 0. Presumably, that's invalid.

Error 5, I probably understand too. It happened when the context ID did not appear in the mdl_context database table. So the message is correct in telling me the context doesn't exist.

Error 3, I don't understand. That's the one I hit when trying to make my user a Teacher in context System.

Error 2, I also don't understand. This occurred when trying to make my user a Manager in context System: that is, when assigning role ID 1 and context ID 1. Isn't that valid?

And error 4, I'm unsure about. It's classified as a "require_login_exception". So something needs logging in? Would that be my user? 

Jocelyn Ireson-Paine

Average of ratings: -
In reply to Jocelyn Ireson-Paine

Re: Am I calling core_role_assign_roles correctly? What do these errors mean?

by Fábio Souto -

Hello Jocelyn,

 

On error 2, despite the error, did the assignment succeed? Could you check it please?

Average of ratings: Useful (1)
In reply to Fábio Souto

Re: Am I calling core_role_assign_roles correctly? What do these errors mean?

by Jocelyn Ireson-Paine -

Hello Fábio, and thanks for the reply. The assignment did succeed, yes. In Site administration > Users > Permissions > Assign system roles, I've just looked at the user, and it has gained role Manager.

Actually, I think I now know what's happening. Just before you replied, I discovered the same error when I ried to delete a user. The error was again:

  <EXCEPTION class="coding_exception">
<MESSAGE>Coding error detected, it must be fixed by a programmer:  PHP catchable fatal error</MESSAGE>   <DEBUGINFO>Argument 1 passed to external_api::clean_returnvalue() must be an instance of external_description, null given, called in    /var/www/moodle/moodle/webservice/rest/locallib.php on line 88 and defined</DEBUGINFO>   </EXCEPTION>

I looked at line 88 of webservice/rest/locallib.php, and saw this code: 

  try {
    $validatedvalues = external_api::clean_returnvalue($this->function->returns_desc, $this->returns);
  } catch (Exception $ex) {
    $exception = $ex;
  }

I then looked at lib/externallib.php. This contains a long function named clean_returnvalue, which checks return values against some kind of template. If they don't match, it throws errors such as 'Scalar type expected, array or object received.'. There's one catch-all error at the end of the function, which is generated by the line:

  throw new invalid_response_exception('Invalid external api response description');

So I suspect that what's going wrong is that Moodle is checking the responses returned by core_user_delete_users and core_role_assign_roles. It's checking them against some description of what they should be. But this description is wrong, and so Moodle is throwing spurious errors.

Am I right? If so, it still leaves the question of why I can assign the Manager role to my user, but not the Student or Teacher roles.

Jocelyn

In reply to Jocelyn Ireson-Paine

Re: Am I calling core_role_assign_roles correctly? What do these errors mean?

by Jocelyn Ireson-Paine -

... and, of course, the question of how to circumvent this problem.

Jocelyn

In reply to Jocelyn Ireson-Paine

Re: Am I calling core_role_assign_roles correctly? What do these errors mean?

by Jérôme Mouneyrac -

Hi Jocelyn,

can you write a tracker issue for 2) explaining how to reproduce?

About your main issue, it is produced because the role you are trying to assign is not returned by: 

$roles = get_assignable_roles($context, ROLENAME_SHORT); // /enrol/externallib.php:362 

I guess this 'get_assignable_roles' core function works well. You may have a misconfiguration in your Moodle.

In reply to Jérôme Mouneyrac

Re: Am I calling core_role_assign_roles correctly? What do these errors mean?

by Jocelyn Ireson-Paine -

Hi Jerome,

I've added it to the tracker as MDL-31082.

I'm still new to Moodle. What kind of misconfiguration might I have? Those role IDs were certainly in my mdl_role table. Also, I managed to use the one for the Student role when I enrolled a user in a course (again using Web services). Should I be able to assign the Student role to a newly created user in System context, or is that illegal?

Jocelyn