Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Miscellaneous callbacks: Difference between revisions

From MoodleDocs
(Adding documentation for override_webservice_execution)
Line 51: Line 51:


== override_webservice_execution ==
== override_webservice_execution ==
{{Moodle 3.6}}


This callback allows an installation to modify the standard behaviour of web service functions. It overrides the execution of the web service - the point where the actual function that does something is about to be called.
This callback allows an installation to modify the standard behaviour of web service functions. It overrides the execution of the web service - the point where the actual function that does something is about to be called.

Revision as of 16:28, 16 January 2019

This page contains documentation for general callbacks available in Moodle plugins.

control_view_profile

This callback allows an installation to control access to a user's profile page. It modifies the response of the user_can_view_profile function; this function is what causes Moodle to show a 'not allowed' error message if you try to view somebody's profile when you aren't allowed to.

You can use this callback if your institution needs to implement policies about who can view profiles in addition to those supported by standard Moodle. Normally it would be implemented in a local plugin, but you can implement in any type of plugin.

Your callback can return one of three values (all constants defined in the core_user class):

VIEWPROFILE_DO_NOT_PREVENT
Use standard Moodle behaviour - apply Moodle's normal rules about whether the current user is allowed to view that profile or not. Your callback should return this if you don't need to change behaviour for the profile in question.
VIEWPROFILE_PREVENT
Prevent the current user from viewing that user's profile, even if Moodle's normal rules would allow it.
VIEWPROFILE_FORCE_ALLOW
Allow the current user to view that user's profile, even if Moodle's normal rules would prevent it.

Example code

This silly example, placed in local/myplugin/lib.php, prevents everyone from accessing the profile of a user 'abc123'.

function local_myplugin_control_view_profile($user, $course = null, context_user $usercontext = null) {

   if ($user->username='abc123') {
       return core_user::VIEWPROFILE_PREVENT;
   }
   return core_user::VIEWPROFILE_DO_NOT_PREVENT;

}

Multiple plugins

The callback can be implemented by multiple plugins. Provided they behave sensibly and return DO_NOT_PREVENT when they don't need to modify behaviour, it should work as expected. The specific rules are:

  • If any function returns VIEWPROFILE_PREVENT then the user will be prevented from viewing the profile.
  • Otherwise, if no function returns VIEWPROFILE_PREVENT but any function returns VIEWPROFILE_FORCE_ALLOW , then the user will be allowed to view the profile.
  • Otherwise all plugins returned VIEWPROFILE_DO_NOT_PREVENT, and Moodle standard behaviour will be used.

store_profiling_data

This callback allows a plugin to get the profiling information from xhprof/tideways-xhprof and do it's own processing or storage with it.

Example code

This is a fragment of a possible plugin that writes files to /tmp/output.

function local_profilestorefile_store_profiling_data($rec) { $file = fopen("/tmp/output/" . $rec->runid, "w") or die("Unable to write to file, does the folder exist?"); fwrite($file, json_encode($rec)); fclose($file); }

override_webservice_execution

Moodle 3.6


This callback allows an installation to modify the standard behaviour of web service functions. It overrides the execution of the web service - the point where the actual function that does something is about to be called.

It works with:

  • Web service calls from the mobile app.
  • Other web service calls using the token system.
  • AJAX web service calls.

You can call the standard function and modify the result, or do something entirely different.

This callback should not be used in core code. It is designed to allow people a way to change the standard behaviour for their instance.

Be aware that when you upgrade to a new Moodle version, the web service that you have overridden may change its definition or behaviour. In that case you would have to update this callback as well.

Usage

The function is called with the web service function object (as returned by external_api::external_function_info) and a numerically-indexed array of the parameters for the function.

  • If the callback wants to override the function, it should return a value in the same format as returned by the real function. Moodle will check this return value to make sure it matches the web service return type definition.
  • If the callback does not want to override the function, it should return false to allow standard execution.

You will probably need to look at the code of the original implementation for the web service function so that you know how it works and what format the results are returned in.

The callback can be implemented by multiple plugins. If it is implemented multiple times then the first function that doesn't return false (in the order that Moodle lists plugins) will be used.

Example code

This example, placed in local/myplugin/lib.php, changes the course list returned by the core_course_get_courses web service function so that it does not include a particular course.

This will have the result of hiding the course from the mobile app. (It may have other undesirable effects within the mobile app - obviously, this override is not officially supported.)

function local_myplugin_override_webservice_execution($function, $params) {

   // Check if it's the function we want to override.
   if ($function->name === 'core_course_get_courses') {
       // Call the original function.
       $result = call_user_func_array([$function->classname, $function->methodname], $params);
       // Get rid of a specific course from the results
       foreach ($result as $index => $course) {
           if ($course['shortname'] === 'SNEAKY') {
               unset($result[$index]);
           }
       }
       $result = array_values($result);
       return $result;
   }
   return false;

}

This second example modifies the core_fetch_notifications function, which is called by AJAX after every page load, to add a notification with the current time:

function local_myplugin_override_webservice_execution($function, $params) {

   // Check if it's the AJAX function that fetches notifications.
   if ($function->name === 'core_fetch_notifications') {
       // Call the original function.
       $result = call_user_func_array([$function->classname, $function->methodname], $params);
       // Add an extra notification.
       $result[] = [
           'template' => 'core/notification_info',
           'variables' => ['message' => 'The time is: ' . date('H:i:s'), 'extraclasses' => ,
               'closebutton' => false, 'announce' => true]
       ];
       return $result;
   }
   return false;

}

Security considerations

This mechanism can bypass security checks. When this function is called, Moodle has checked the user's token or basic access but other checks have not yet been done.

  • If you call the original function, that function will apply its security checks as normal, so this part should be safe.
  • If you add extra data to the result, or extra functionality, make sure you have checked the appropriate permissions for the current user.
  • If you replace the original function, make sure you do all the relevant security checks (look at the source code of the original function).