Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.

Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  use core_external\external_api;
  18  use core_external\external_value;
  19  use core_external\external_format_value;
  20  use core_external\external_single_structure;
  21  use core_external\external_multiple_structure;
  22  use core_external\external_function_parameters;
  23  use core_external\external_warnings;
  24  
  25  /**
  26   * Tags-related web services
  27   *
  28   * @package    core_tag
  29   * @copyright  2015 Marina Glancy
  30   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  31   */
  32  class core_tag_external extends external_api {
  33  
  34      /**
  35       * Parameters for function update_tags()
  36       *
  37       * @return external_function_parameters
  38       */
  39      public static function update_tags_parameters() {
  40          return new external_function_parameters(
  41              array(
  42                  'tags' => new external_multiple_structure(
  43                      new external_single_structure(
  44                          array(
  45                              'id' => new external_value(PARAM_INT, 'tag id'),
  46                              'rawname' => new external_value(PARAM_RAW, 'tag raw name (may contain capital letters)',
  47                                      VALUE_OPTIONAL),
  48                              'description' => new external_value(PARAM_RAW, 'tag description', VALUE_OPTIONAL),
  49                              'descriptionformat' => new external_value(PARAM_INT, 'tag description format', VALUE_OPTIONAL),
  50                              'flag' => new external_value(PARAM_INT, 'flag', VALUE_OPTIONAL),
  51                              'official' => new external_value(PARAM_INT,
  52                                  '(deprecated, use isstandard) whether this flag is standard', VALUE_OPTIONAL),
  53                              'isstandard' => new external_value(PARAM_INT, 'whether this flag is standard', VALUE_OPTIONAL),
  54                          )
  55                      )
  56                  )
  57              )
  58          );
  59      }
  60  
  61      /**
  62       * Update tags
  63       *
  64       * @param array $tags
  65       */
  66      public static function update_tags($tags) {
  67          global $CFG, $PAGE, $DB;
  68  
  69          // Validate and normalize parameters.
  70          $tags = self::validate_parameters(self::update_tags_parameters(), array('tags' => $tags));
  71  
  72          $systemcontext = context_system::instance();
  73          $canmanage = has_capability('moodle/tag:manage', $systemcontext);
  74          $canedit = has_capability('moodle/tag:edit', $systemcontext);
  75          $warnings = array();
  76  
  77          if (empty($CFG->usetags)) {
  78              throw new moodle_exception('tagsaredisabled', 'tag');
  79          }
  80  
  81          $renderer = $PAGE->get_renderer('core');
  82          foreach ($tags['tags'] as $tag) {
  83              $tag = (array)$tag;
  84              if (array_key_exists('rawname', $tag)) {
  85                  $tag['rawname'] = clean_param($tag['rawname'], PARAM_TAG);
  86                  if (empty($tag['rawname'])) {
  87                      unset($tag['rawname']);
  88                  }
  89              }
  90              if (!$canmanage) {
  91                  // User without manage capability can not change any fields except for descriptions.
  92                  $tag = array_intersect_key($tag, array('id' => 1,
  93                      'description' => 1, 'descriptionformat' => 1));
  94              }
  95              if (!$canedit) {
  96                  // User without edit capability can not change description.
  97                  $tag = array_diff_key($tag,
  98                          array('description' => 1, 'descriptionformat' => 1));
  99              }
 100              if (count($tag) <= 1) {
 101                  $warnings[] = array(
 102                      'item' => $tag['id'],
 103                      'warningcode' => 'nothingtoupdate',
 104                      'message' => get_string('nothingtoupdate', 'core_tag')
 105                  );
 106                  continue;
 107              }
 108              if (!$tagobject = core_tag_tag::get($tag['id'], '*')) {
 109                  $warnings[] = array(
 110                      'item' => $tag['id'],
 111                      'warningcode' => 'tagnotfound',
 112                      'message' => get_string('tagnotfound', 'error')
 113                  );
 114                  continue;
 115              }
 116              // First check if new tag name is allowed.
 117              if (!empty($tag['rawname']) && ($existing = core_tag_tag::get_by_name($tagobject->tagcollid, $tag['rawname']))) {
 118                  if ($existing->id != $tag['id']) {
 119                      $warnings[] = array(
 120                          'item' => $tag['id'],
 121                          'warningcode' => 'namesalreadybeeingused',
 122                          'message' => get_string('namesalreadybeeingused', 'core_tag')
 123                      );
 124                      continue;
 125                  }
 126              }
 127              if (array_key_exists('official', $tag)) {
 128                  // Parameter 'official' deprecated and replaced with 'isstandard'.
 129                  $tag['isstandard'] = $tag['official'] ? 1 : 0;
 130                  unset($tag['official']);
 131              }
 132              if (isset($tag['flag'])) {
 133                  if ($tag['flag']) {
 134                      $tagobject->flag();
 135                  } else {
 136                      $tagobject->reset_flag();
 137                  }
 138                  unset($tag['flag']);
 139              }
 140              unset($tag['id']);
 141              if (count($tag)) {
 142                  $tagobject->update($tag);
 143              }
 144          }
 145          return array('warnings' => $warnings);
 146      }
 147  
 148      /**
 149       * Return structure for update_tag()
 150       *
 151       * @return \core_external\external_description
 152       */
 153      public static function update_tags_returns() {
 154          return new external_single_structure(
 155              array(
 156                  'warnings' => new external_warnings()
 157              )
 158          );
 159      }
 160  
 161      /**
 162       * Parameters for function get_tags()
 163       *
 164       * @return external_function_parameters
 165       */
 166      public static function get_tags_parameters() {
 167          return new external_function_parameters(
 168              array(
 169                  'tags' => new external_multiple_structure(
 170                      new external_single_structure(
 171                          array(
 172                              'id' => new external_value(PARAM_INT, 'tag id'),
 173                          )
 174                      )
 175                  )
 176              )
 177          );
 178      }
 179  
 180      /**
 181       * Get tags by their ids
 182       *
 183       * @param array $tags
 184       */
 185      public static function get_tags($tags) {
 186          global $CFG, $PAGE, $DB;
 187  
 188          // Validate and normalize parameters.
 189          $tags = self::validate_parameters(self::get_tags_parameters(), array('tags' => $tags));
 190  
 191          $systemcontext = context_system::instance();
 192          self::validate_context($systemcontext);
 193  
 194          $canmanage = has_capability('moodle/tag:manage', $systemcontext);
 195          $canedit = has_capability('moodle/tag:edit', $systemcontext);
 196  
 197          $return = array();
 198          $warnings = array();
 199  
 200          if (empty($CFG->usetags)) {
 201              throw new moodle_exception('tagsaredisabled', 'tag');
 202          }
 203  
 204          $renderer = $PAGE->get_renderer('core');
 205          foreach ($tags['tags'] as $tag) {
 206              $tag = (array)$tag;
 207              if (!$tagobject = $DB->get_record('tag', array('id' => $tag['id']))) {
 208                  $warnings[] = array(
 209                      'item' => $tag['id'],
 210                      'warningcode' => 'tagnotfound',
 211                      'message' => get_string('tagnotfound', 'error')
 212                  );
 213                  continue;
 214              }
 215              $tagoutput = new \core_tag\output\tag($tagobject);
 216              // Do not return some information to users without permissions.
 217              $rv = $tagoutput->export_for_template($renderer);
 218              if (!$canmanage) {
 219                  if (!$canedit) {
 220                      unset($rv->isstandard);
 221                      unset($rv->official);
 222                  }
 223                  unset($rv->flag);
 224              }
 225              $return[] = $rv;
 226          }
 227          return array('tags' => $return, 'warnings' => $warnings);
 228      }
 229  
 230      /**
 231       * Return structure for get_tag()
 232       *
 233       * @return \core_external\external_description
 234       */
 235      public static function get_tags_returns() {
 236          return new external_single_structure(
 237              array(
 238                  'tags' => new external_multiple_structure( new external_single_structure(
 239                      array(
 240                          'id' => new external_value(PARAM_INT, 'tag id'),
 241                          'tagcollid' => new external_value(PARAM_INT, 'tag collection id'),
 242                          'name' => new external_value(PARAM_TAG, 'name'),
 243                          'rawname' => new external_value(PARAM_RAW, 'tag raw name (may contain capital letters)'),
 244                          'description' => new external_value(PARAM_RAW, 'tag description'),
 245                          'descriptionformat' => new external_format_value(PARAM_INT, VALUE_REQUIRED, 'tag description format'),
 246                          'flag' => new external_value(PARAM_INT, 'flag', VALUE_OPTIONAL),
 247                          'official' => new external_value(PARAM_INT,
 248                              'whether this flag is standard (deprecated, use isstandard)', VALUE_OPTIONAL),
 249                          'isstandard' => new external_value(PARAM_INT, 'whether this flag is standard', VALUE_OPTIONAL),
 250                          'viewurl' => new external_value(PARAM_URL, 'URL to view'),
 251                      ), 'information about one tag')
 252                  ),
 253                  'warnings' => new external_warnings()
 254              )
 255          );
 256      }
 257  
 258      /**
 259       * Parameters for function get_tagindex()
 260       *
 261       * @return external_function_parameters
 262       */
 263      public static function get_tagindex_parameters() {
 264          return new external_function_parameters(
 265              array(
 266                  'tagindex' => new external_single_structure(array(
 267                      'tag' => new external_value(PARAM_TAG, 'tag name'),
 268                      'tc' => new external_value(PARAM_INT, 'tag collection id'),
 269                      'ta' => new external_value(PARAM_INT, 'tag area id'),
 270                      'excl' => new external_value(PARAM_BOOL, 'exlusive mode for this tag area', VALUE_OPTIONAL, 0),
 271                      'from' => new external_value(PARAM_INT, 'context id where the link was displayed', VALUE_OPTIONAL, 0),
 272                      'ctx' => new external_value(PARAM_INT, 'context id where to search for items', VALUE_OPTIONAL, 0),
 273                      'rec' => new external_value(PARAM_INT, 'search in the context recursive', VALUE_OPTIONAL, 1),
 274                      'page' => new external_value(PARAM_INT, 'page number (0-based)', VALUE_OPTIONAL, 0),
 275                  ), 'parameters')
 276              )
 277          );
 278      }
 279  
 280      /**
 281       * Get tags by their ids
 282       *
 283       * @param array $params
 284       */
 285      public static function get_tagindex($params) {
 286          global $PAGE;
 287          // Validate and normalize parameters.
 288          $tagindex = self::validate_parameters(
 289                  self::get_tagindex_parameters(), array('tagindex' => $params));
 290          $params = $tagindex['tagindex'] + array(
 291              'excl' => 0,
 292              'from' => 0,
 293              'ctx' => 0,
 294              'rec' => 1,
 295              'page' => 0
 296          );
 297  
 298          // Login to the course / module if applicable.
 299          $context = $params['ctx'] ? context::instance_by_id($params['ctx']) : context_system::instance();
 300          self::validate_context($context);
 301  
 302          $tag = core_tag_tag::get_by_name($params['tc'], $params['tag'], '*', MUST_EXIST);
 303          $tagareas = core_tag_collection::get_areas($params['tc']);
 304          $tagindex = $tag->get_tag_index($tagareas[$params['ta']], $params['excl'], $params['from'],
 305                  $params['ctx'], $params['rec'], $params['page']);
 306          $renderer = $PAGE->get_renderer('core');
 307          return $tagindex->export_for_template($renderer);
 308      }
 309  
 310      /**
 311       * Return structure for get_tag()
 312       *
 313       * @return \core_external\external_description
 314       */
 315      public static function get_tagindex_returns() {
 316          return new external_single_structure(
 317              array(
 318                  'tagid' => new external_value(PARAM_INT, 'tag id'),
 319                  'ta' => new external_value(PARAM_INT, 'tag area id'),
 320                  'component' => new external_value(PARAM_COMPONENT, 'component'),
 321                  'itemtype' => new external_value(PARAM_NOTAGS, 'itemtype'),
 322                  'nextpageurl' => new external_value(PARAM_URL, 'URL for the next page', VALUE_OPTIONAL),
 323                  'prevpageurl' => new external_value(PARAM_URL, 'URL for the next page', VALUE_OPTIONAL),
 324                  'exclusiveurl' => new external_value(PARAM_URL, 'URL for exclusive link', VALUE_OPTIONAL),
 325                  'exclusivetext' => new external_value(PARAM_TEXT, 'text for exclusive link', VALUE_OPTIONAL),
 326                  'title' => new external_value(PARAM_RAW, 'title'),
 327                  'content' => new external_value(PARAM_RAW, 'title'),
 328                  'hascontent' => new external_value(PARAM_INT, 'whether the content is present'),
 329                  'anchor' => new external_value(PARAM_TEXT, 'name of anchor', VALUE_OPTIONAL),
 330              ), 'tag index'
 331          );
 332      }
 333  
 334  
 335      /**
 336       * Parameters for function get_tagindex_per_area()
 337       *
 338       * @return external_function_parameters
 339       * @since  Moodle 3.7
 340       */
 341      public static function get_tagindex_per_area_parameters() {
 342          return new external_function_parameters(
 343              array(
 344                  'tagindex' => new external_single_structure(array(
 345                      'id' => new external_value(PARAM_INT, 'tag id', VALUE_OPTIONAL, 0),
 346                      'tag' => new external_value(PARAM_TAG, 'tag name', VALUE_OPTIONAL, ''),
 347                      'tc' => new external_value(PARAM_INT, 'tag collection id', VALUE_OPTIONAL, 0),
 348                      'ta' => new external_value(PARAM_INT, 'tag area id', VALUE_OPTIONAL, 0),
 349                      'excl' => new external_value(PARAM_BOOL, 'exlusive mode for this tag area', VALUE_OPTIONAL, 0),
 350                      'from' => new external_value(PARAM_INT, 'context id where the link was displayed', VALUE_OPTIONAL, 0),
 351                      'ctx' => new external_value(PARAM_INT, 'context id where to search for items', VALUE_OPTIONAL, 0),
 352                      'rec' => new external_value(PARAM_INT, 'search in the context recursive', VALUE_OPTIONAL, 1),
 353                      'page' => new external_value(PARAM_INT, 'page number (0-based)', VALUE_OPTIONAL, 0),
 354                  ), 'parameters')
 355              )
 356          );
 357      }
 358  
 359      /**
 360       * Returns the tag index per multiple areas if requested.
 361       *
 362       * @param array $params Tag index required information.
 363       * @throws moodle_exception
 364       * @since  Moodle 3.7
 365       */
 366      public static function get_tagindex_per_area($params) {
 367          global $CFG, $PAGE;
 368          // Validate and normalize parameters.
 369          $tagindex = self::validate_parameters(
 370              self::get_tagindex_per_area_parameters(), array('tagindex' => $params));
 371          $params = $tagindex['tagindex'] + array(    // Force defaults.
 372              'id' => 0,
 373              'tag' => '',
 374              'tc' => 0,
 375              'ta' => 0,
 376              'excl' => 0,
 377              'from' => 0,
 378              'ctx' => 0,
 379              'rec' => 1,
 380              'page' => 0,
 381          );
 382  
 383          if (empty($CFG->usetags)) {
 384              throw new moodle_exception('tagsaredisabled', 'tag');
 385          }
 386  
 387          if (!empty($params['tag'])) {
 388              if (empty($params['tc'])) {
 389                  // Tag name specified but tag collection was not. Try to guess it.
 390                  $tags = core_tag_tag::guess_by_name($params['tag'], '*');
 391                  if (count($tags) > 1) {
 392                      // It is in more that one collection, do not display.
 393                      throw new moodle_exception('Tag is in more that one collection, please indicate one.');
 394                  } else if (count($tags) == 1) {
 395                      $tag = reset($tags);
 396                  }
 397              } else {
 398                  if (!$tag = core_tag_tag::get_by_name($params['tc'], $params['tag'], '*')) {
 399                      // Not found in collection.
 400                      throw new moodle_exception('notagsfound', 'tag');
 401                  }
 402              }
 403          } else if (!empty($params['id'])) {
 404              $tag = core_tag_tag::get($params['id'], '*');
 405          }
 406  
 407          if (empty($tag)) {
 408              throw new moodle_exception('notagsfound', 'tag');
 409          }
 410  
 411          // Login to the course / module if applicable.
 412          $context = !empty($params['ctx']) ? context::instance_by_id($params['ctx']) : context_system::instance();
 413          self::validate_context($context);
 414  
 415          $tag = core_tag_tag::get_by_name($params['tc'], $tag->name, '*', MUST_EXIST);
 416          $tagareas = core_tag_collection::get_areas($params['tc']);
 417          $tagareaid = $params['ta'];
 418  
 419           $exclusivemode = 0;
 420          // Find all areas in this collection and their items tagged with this tag.
 421          if ($tagareaid) {
 422              $tagareas = array($tagareas[$tagareaid]);
 423          }
 424          if (!$tagareaid && count($tagareas) == 1) {
 425              // Automatically set "exclusive" mode for tag collection with one tag area only.
 426              $params['excl'] = 1;
 427          }
 428  
 429          $renderer = $PAGE->get_renderer('core');
 430          $result = array();
 431          foreach ($tagareas as $ta) {
 432              $tagindex = $tag->get_tag_index($ta, $params['excl'], $params['from'], $params['ctx'], $params['rec'], $params['page']);
 433              if (!empty($tagindex->hascontent)) {
 434                  $result[] = $tagindex->export_for_template($renderer);
 435              }
 436          }
 437          return $result;
 438      }
 439  
 440      /**
 441       * Return structure for get_tagindex_per_area
 442       *
 443       * @return \core_external\external_description
 444       * @since  Moodle 3.7
 445       */
 446      public static function get_tagindex_per_area_returns() {
 447          return new external_multiple_structure(
 448              self::get_tagindex_returns()
 449          );
 450      }
 451  
 452      /**
 453       * Returns description of get_tag_areas() parameters.
 454       *
 455       * @return external_function_parameters
 456       * @since  Moodle 3.7
 457       */
 458      public static function get_tag_areas_parameters() {
 459          return new external_function_parameters(array());
 460      }
 461  
 462      /**
 463       * Retrieves existing tag areas.
 464       *
 465       * @return array an array of warnings and objects containing the plugin information
 466       * @throws moodle_exception
 467       * @since  Moodle 3.7
 468       */
 469      public static function get_tag_areas() {
 470          global $CFG, $PAGE;
 471  
 472          if (empty($CFG->usetags)) {
 473              throw new moodle_exception('tagsaredisabled', 'tag');
 474          }
 475  
 476          $context = context_system::instance();
 477          self::validate_context($context);
 478          $PAGE->set_context($context); // Needed by internal APIs.
 479          $output = $PAGE->get_renderer('core');
 480  
 481          $areas = core_tag_area::get_areas();
 482          $exportedareas = array();
 483          foreach ($areas as $itemtype => $component) {
 484              foreach ($component as $area) {
 485                  // Move optional fields not part of the DB table to otherdata.
 486                  $locked = false;
 487                  if (isset($area->locked)) {
 488                      $locked = $area->locked;
 489                      unset($area->locked);
 490                  }
 491                  $exporter = new \core_tag\external\tag_area_exporter($area, array('locked' => $locked));
 492                  $exportedareas[] = $exporter->export($output);
 493              }
 494          }
 495  
 496          return array(
 497              'areas' => $exportedareas,
 498              'warnings' => array(),
 499          );
 500      }
 501  
 502      /**
 503       * Returns description of get_tag_areas() result value.
 504       *
 505       * @return \core_external\external_description
 506       * @since  Moodle 3.7
 507       */
 508      public static function get_tag_areas_returns() {
 509          return new external_single_structure(
 510              array(
 511                  'areas' => new external_multiple_structure(
 512                      \core_tag\external\tag_area_exporter::get_read_structure()
 513                  ),
 514                  'warnings' => new external_warnings(),
 515              )
 516          );
 517      }
 518  
 519      /**
 520       * Returns description of get_tag_collections() parameters.
 521       *
 522       * @return external_function_parameters
 523       * @since  Moodle 3.7
 524       */
 525      public static function get_tag_collections_parameters() {
 526          return new external_function_parameters(array());
 527      }
 528  
 529      /**
 530       * Retrieves existing tag collections.
 531       *
 532       * @return array an array of warnings and tag collections
 533       * @throws moodle_exception
 534       * @since  Moodle 3.7
 535       */
 536      public static function get_tag_collections() {
 537          global $CFG, $PAGE;
 538  
 539          if (empty($CFG->usetags)) {
 540              throw new moodle_exception('tagsaredisabled', 'tag');
 541          }
 542  
 543          $context = context_system::instance();
 544          self::validate_context($context);
 545          $PAGE->set_context($context); // Needed by internal APIs.
 546          $output = $PAGE->get_renderer('core');
 547  
 548          $collections = core_tag_collection::get_collections();
 549          $exportedcollections = array();
 550          foreach ($collections as $collection) {
 551              $exporter = new \core_tag\external\tag_collection_exporter($collection);
 552              $exportedcollections[] = $exporter->export($output);
 553          }
 554  
 555          return array(
 556              'collections' => $exportedcollections,
 557              'warnings' => array(),
 558          );
 559      }
 560  
 561      /**
 562       * Returns description of get_tag_collections() result value.
 563       *
 564       * @return \core_external\external_description
 565       * @since  Moodle 3.7
 566       */
 567      public static function get_tag_collections_returns() {
 568          return new external_single_structure(
 569              array(
 570                  'collections' => new external_multiple_structure(
 571                      \core_tag\external\tag_collection_exporter::get_read_structure()
 572                  ),
 573                  'warnings' => new external_warnings(),
 574              )
 575          );
 576      }
 577  
 578      /**
 579       * Returns description of get_tag_cloud() parameters.
 580       *
 581       * @return external_function_parameters
 582       * @since  Moodle 3.7
 583       */
 584      public static function get_tag_cloud_parameters() {
 585          return new external_function_parameters(
 586              array(
 587                  'tagcollid' => new external_value(PARAM_INT, 'Tag collection id.', VALUE_DEFAULT, 0),
 588                  'isstandard' => new external_value(PARAM_BOOL, 'Whether to return only standard tags.', VALUE_DEFAULT, false),
 589                  'limit' => new external_value(PARAM_INT, 'Maximum number of tags to retrieve.', VALUE_DEFAULT, 150),
 590                  'sort' => new external_value(PARAM_ALPHA, 'Sort order for display
 591                      (id, name, rawname, count, flag, isstandard, tagcollid).', VALUE_DEFAULT, 'name'),
 592                  'search' => new external_value(PARAM_RAW, 'Search string.', VALUE_DEFAULT, ''),
 593                  'fromctx' => new external_value(PARAM_INT, 'Context id where this tag cloud is displayed.', VALUE_DEFAULT, 0),
 594                  'ctx' => new external_value(PARAM_INT, 'Only retrieve tag instances in this context.', VALUE_DEFAULT, 0),
 595                  'rec' => new external_value(PARAM_INT, 'Retrieve tag instances in the $ctx context and it\'s children.',
 596                      VALUE_DEFAULT, 1),
 597              )
 598          );
 599      }
 600  
 601      /**
 602       * Retrieves a tag cloud for display.
 603       *
 604       * @param int $tagcollid tag collection id
 605       * @param bool $isstandard return only standard tags
 606       * @param int $limit maximum number of tags to retrieve, tags are sorted by the instance count
 607       *            descending here regardless of $sort parameter
 608       * @param string $sort sort order for display, default 'name' - tags will be sorted after they are retrieved
 609       * @param string $search search string
 610       * @param int $fromctx context id where this tag cloud is displayed
 611       * @param int $ctx only retrieve tag instances in this context
 612       * @param int $rec retrieve tag instances in the $ctx context and it's children (default 1)
 613       * @return array an array of warnings and tag cloud information and items
 614       * @throws moodle_exception
 615       * @since  Moodle 3.7
 616       */
 617      public static function get_tag_cloud($tagcollid = 0, $isstandard = false, $limit = 150, $sort = 'name',
 618              $search = '', $fromctx = 0, $ctx = 0, $rec = 1) {
 619          global $CFG, $PAGE;
 620  
 621          $params = self::validate_parameters(self::get_tag_cloud_parameters(),
 622              array(
 623                  'tagcollid' => $tagcollid,
 624                  'isstandard' => $isstandard,
 625                  'limit' => $limit,
 626                  'sort' => $sort,
 627                  'search' => $search,
 628                  'fromctx' => $fromctx,
 629                  'ctx' => $ctx,
 630                  'rec' => $rec,
 631              )
 632          );
 633  
 634          if (empty($CFG->usetags)) {
 635              throw new moodle_exception('tagsaredisabled', 'tag');
 636          }
 637  
 638          $context = context_system::instance();
 639          self::validate_context($context);
 640          $PAGE->set_context($context); // Needed by internal APIs.
 641          $output = $PAGE->get_renderer('core');
 642  
 643          $tagcloud = core_tag_collection::get_tag_cloud($params['tagcollid'], $params['isstandard'], $params['limit'],
 644              $params['sort'], $params['search'], $params['fromctx'], $params['ctx'], $params['rec']);
 645  
 646          $result = $tagcloud->export_for_template($output);
 647          $result->warnings = array();
 648  
 649          return (array) $result;
 650      }
 651  
 652      /**
 653       * Returns description of get_tag_cloud() result value.
 654       *
 655       * @return \core_external\external_description
 656       * @since  Moodle 3.7
 657       */
 658      public static function get_tag_cloud_returns() {
 659          return new external_single_structure(
 660              array(
 661                  'tags' => new external_multiple_structure(
 662                      new external_single_structure(
 663                          array(
 664                              'name' => new external_value(PARAM_TAG, 'Tag name.'),
 665                              'viewurl' => new external_value(PARAM_RAW, 'URL to view the tag index.'),
 666                              'flag' => new external_value(PARAM_BOOL, 'Whether the tag is flagged as inappropriate.',
 667                                  VALUE_OPTIONAL),
 668                              'isstandard' => new external_value(PARAM_BOOL, 'Whether is a standard tag or not.', VALUE_OPTIONAL),
 669                              'count' => new external_value(PARAM_INT, 'Number of tag instances.', VALUE_OPTIONAL),
 670                              'size' => new external_value(PARAM_INT, 'Proportional size to display the tag.', VALUE_OPTIONAL),
 671                          ), 'Tags.'
 672                      )
 673                  ),
 674                  'tagscount' => new external_value(PARAM_INT, 'Number of tags returned.'),
 675                  'totalcount' => new external_value(PARAM_INT, 'Total count of tags.'),
 676                  'warnings' => new external_warnings(),
 677              )
 678          );
 679      }
 680  }