. /** * Helper functions for web services * @package local_treestudyplan * @copyright 2023 P.M. Kuipers * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace local_treestudyplan\local\helpers; use core_course_category; use local_treestudyplan\courseservice; use local_treestudyplan\debug; defined('MOODLE_INTERNAL') || die(); require_once($CFG->dirroot.'/webservice/lib.php'); /** * Class containing helper functions for webservices */ class webservicehelper { /** @var \context_system */ private static $systemcontext = null; /** @var \context[] */ private static $validatedcontexts = []; /** * Test for capability in the given context for the current user and throw a \webservice_access_exception if not * Note: The context is not validate * @param array|string $capability One or more capabilities to be tested OR wise * @param \context $context The context in which to check for the capability. * @throws \webservice_access_exception If none of the capabilities provided are given to the current user * @return boolean */ public static function has_capabilities($capability, $context) { if ($context == null) { $context = \context_system::instance(); } if (is_array($capability)) { return \has_any_capability($capability, $context); } else { return has_capability($capability, $context); } } /** * Test if the current user has a certain capability in any of the categories they have access to * @param string $capability The capability to scan for in the categories * @param int|null $userid Userid to use in check (Use current user if null or empty) * @return boolean */ public static function has_capability_in_any_category($capability, $userid=null ) { global $USER; if ($userid == null) { $userid = $USER->id; } $list = courseservice::user_tops($userid, $capability); return boolval(count($list) > 0); } /** * Test for capability in the given context for the current user and throw a \webservice_access_exception if not * @param array|string $capability One or more capabilities to be tested OR wise * @param \context $context The context in which to check for the capability. Leave empty to use the system context. * @param bool $validate Validate the context before checking capabilities * @throws \webservice_access_exception If none of the capabilities provided are given to the current user */ public static function require_capabilities($capability, $context = null, $validate = true) { if ($validate) { \external_api::validate_context($context); } if (! static::has_capabilities($capability, $context)) { throw new \webservice_access_exception( "The capability {$capability} is required on this context ({$context->get_context_name()})" ); } } /** * Find and validate a given context by id * @param int $contextid The id of the context * @return \context The found context by id * @throws \InvalidArgumentException When the context is not found */ public static function find_context($contextid): \context { if (isset($contextid) && is_int($contextid) && $contextid > 0) { if (!in_array($contextid, self::$validatedcontexts)) { // Cache the context and make sure it is only validated once... try { $context = \context::instance_by_id($contextid); } catch (\dml_missing_record_exception $x) { // Just throw it up again. catch is included here to make sure we know it throws this exception. throw new \InvalidArgumentException("Context {$contextid} not available"); } // Validate the found context. \external_api::validate_context($context); self::$validatedcontexts[$contextid] = $context; } return self::$validatedcontexts[$contextid]; } else { return static::system_context(); // This function ensures the system context is validated just once this call. } } /** * Return the validated system context (validation happens only once for this call) * @return \context_system The system context, validated to use as this context */ public static function system_context(): \context_system { if (!isset(static::$systemcontext)) { static::$systemcontext = \context_system::instance(); \external_api::validate_context(static::$systemcontext); } return static::$systemcontext; } }