Search moodle.org's
Developer Documentation

See Release Notes

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

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

   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  /**
  18   * Blocks external API
  19   *
  20   * @package    core_block
  21   * @category   external
  22   * @copyright  2017 Juan Leyva <juan@moodle.com>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   * @since      Moodle 3.3
  25   */
  26  
  27  use core_external\external_api;
  28  use core_external\external_files;
  29  use core_external\external_format_value;
  30  use core_external\external_function_parameters;
  31  use core_external\external_multiple_structure;
  32  use core_external\external_single_structure;
  33  use core_external\external_value;
  34  use core_external\external_warnings;
  35  
  36  defined('MOODLE_INTERNAL') || die;
  37  
  38  require_once("$CFG->dirroot/my/lib.php");
  39  
  40  /**
  41   * Blocks external functions
  42   *
  43   * @package    core_block
  44   * @category   external
  45   * @copyright  2015 Juan Leyva <juan@moodle.com>
  46   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  47   * @since      Moodle 3.3
  48   */
  49  class core_block_external extends external_api {
  50  
  51  
  52      /**
  53       * Returns a block structure.
  54       *
  55       * @return external_single_structure a block single structure.
  56       * @since  Moodle 3.6
  57       */
  58      private static function get_block_structure() {
  59          return new external_single_structure(
  60              array(
  61                  'instanceid'    => new external_value(PARAM_INT, 'Block instance id.'),
  62                  'name'          => new external_value(PARAM_PLUGIN, 'Block name.'),
  63                  'region'        => new external_value(PARAM_ALPHANUMEXT, 'Block region.'),
  64                  'positionid'    => new external_value(PARAM_INT, 'Position id.'),
  65                  'collapsible'   => new external_value(PARAM_BOOL, 'Whether the block is collapsible.'),
  66                  'dockable'      => new external_value(PARAM_BOOL, 'Whether the block is dockable.'),
  67                  'weight'        => new external_value(PARAM_INT, 'Used to order blocks within a region.', VALUE_OPTIONAL),
  68                  'visible'       => new external_value(PARAM_BOOL, 'Whether the block is visible.', VALUE_OPTIONAL),
  69                  'contents'      => new external_single_structure(
  70                      array(
  71                          'title'         => new external_value(PARAM_RAW, 'Block title.'),
  72                          'content'       => new external_value(PARAM_RAW, 'Block contents.'),
  73                          'contentformat' => new external_format_value('content'),
  74                          'footer'        => new external_value(PARAM_RAW, 'Block footer.'),
  75                          'files'         => new external_files('Block files.'),
  76                      ),
  77                      'Block contents (if required).', VALUE_OPTIONAL
  78                  ),
  79                  'configs' => new external_multiple_structure(
  80                      new external_single_structure(
  81                          array(
  82                              'name' => new external_value(PARAM_RAW, 'Name.'),
  83                              'value' => new external_value(PARAM_RAW, 'JSON encoded representation of the config value.'),
  84                              'type' => new external_value(PARAM_ALPHA, 'Type (instance or plugin).'),
  85                          )
  86                      ),
  87                      'Block instance and plugin configuration settings.', VALUE_OPTIONAL
  88                  ),
  89              ), 'Block information.'
  90          );
  91      }
  92  
  93      /**
  94       * Convenience function for getting all the blocks of the current $PAGE.
  95       *
  96       * @param bool $includeinvisible Whether to include not visible blocks or not
  97       * @param bool $returncontents Whether to return the block contents
  98       * @return array Block information
  99       * @since  Moodle 3.6
 100       */
 101      private static function get_all_current_page_blocks($includeinvisible = false, $returncontents = false) {
 102          global $PAGE, $OUTPUT;
 103  
 104          // Set page URL to a fake URL to avoid errors.
 105          $PAGE->set_url(new \moodle_url('/webservice/core_block_external/'));
 106  
 107          // Load the block instances for all the regions.
 108          $PAGE->blocks->load_blocks($includeinvisible);
 109          $PAGE->blocks->create_all_block_instances();
 110  
 111          $allblocks = array();
 112          $blocks = $PAGE->blocks->get_content_for_all_regions($OUTPUT);
 113          foreach ($blocks as $region => $regionblocks) {
 114              $regioninstances = $PAGE->blocks->get_blocks_for_region($region);
 115              // Index block instances to retrieve required info.
 116              $blockinstances = array();
 117              foreach ($regioninstances as $ri) {
 118                  $blockinstances[$ri->instance->id] = $ri;
 119              }
 120  
 121              foreach ($regionblocks as $bc) {
 122                  $block = [
 123                      'instanceid' => $bc->blockinstanceid,
 124                      'name' => $blockinstances[$bc->blockinstanceid]->instance->blockname,
 125                      'region' => $region,
 126                      'positionid' => $bc->blockpositionid,
 127                      'collapsible' => (bool) $bc->collapsible,
 128                      'dockable' => (bool) $bc->dockable,
 129                      'weight' => $blockinstances[$bc->blockinstanceid]->instance->weight,
 130                      'visible' => $blockinstances[$bc->blockinstanceid]->instance->visible,
 131                  ];
 132                  if ($returncontents) {
 133                      $block['contents'] = (array) $blockinstances[$bc->blockinstanceid]->get_content_for_external($OUTPUT);
 134                  }
 135                  $configs = (array) $blockinstances[$bc->blockinstanceid]->get_config_for_external();
 136                  foreach ($configs as $type => $data) {
 137                      foreach ((array) $data as $name => $value) {
 138                          $block['configs'][] = [
 139                              'name' => $name,
 140                              'value' => json_encode($value), // Always JSON encode, we may receive non-scalar values.
 141                              'type' => $type,
 142                          ];
 143                      }
 144                  }
 145  
 146                  $allblocks[] = $block;
 147              }
 148          }
 149          return $allblocks;
 150      }
 151  
 152      /**
 153       * Returns description of get_course_blocks parameters.
 154       *
 155       * @return external_function_parameters
 156       * @since Moodle 3.3
 157       */
 158      public static function get_course_blocks_parameters() {
 159          return new external_function_parameters(
 160              array(
 161                  'courseid'  => new external_value(PARAM_INT, 'course id'),
 162                  'returncontents' => new external_value(PARAM_BOOL, 'Whether to return the block contents.', VALUE_DEFAULT, false),
 163              )
 164          );
 165      }
 166  
 167      /**
 168       * Returns blocks information for a course.
 169       *
 170       * @param int $courseid The course id
 171       * @param bool $returncontents Whether to return the block contents
 172       * @return array Blocks list and possible warnings
 173       * @throws moodle_exception
 174       * @since Moodle 3.3
 175       */
 176      public static function get_course_blocks($courseid, $returncontents = false) {
 177          global $PAGE;
 178  
 179          $warnings = array();
 180          $params = self::validate_parameters(self::get_course_blocks_parameters(),
 181              ['courseid' => $courseid, 'returncontents' => $returncontents]);
 182  
 183          $course = get_course($params['courseid']);
 184          $context = context_course::instance($course->id);
 185          self::validate_context($context);
 186  
 187          // Specific layout for frontpage course.
 188          if ($course->id == SITEID) {
 189              $PAGE->set_pagelayout('frontpage');
 190              $PAGE->set_pagetype('site-index');
 191          } else {
 192              $PAGE->set_pagelayout('course');
 193              // Ensure course format is set (view course/view.php).
 194              $course->format = course_get_format($course)->get_format();
 195              $PAGE->set_pagetype('course-view-' . $course->format);
 196          }
 197  
 198          $allblocks = self::get_all_current_page_blocks(false, $params['returncontents']);
 199  
 200          return array(
 201              'blocks' => $allblocks,
 202              'warnings' => $warnings
 203          );
 204      }
 205  
 206      /**
 207       * Returns description of get_course_blocks result values.
 208       *
 209       * @return external_single_structure
 210       * @since Moodle 3.3
 211       */
 212      public static function get_course_blocks_returns() {
 213  
 214          return new external_single_structure(
 215              array(
 216                  'blocks' => new external_multiple_structure(self::get_block_structure(), 'List of blocks in the course.'),
 217                  'warnings'  => new external_warnings(),
 218              )
 219          );
 220      }
 221  
 222      /**
 223       * Returns description of get_dashboard_blocks parameters.
 224       *
 225       * @return external_function_parameters
 226       * @since Moodle 3.6
 227       */
 228      public static function get_dashboard_blocks_parameters() {
 229          return new external_function_parameters(
 230              array(
 231                  'userid'  => new external_value(PARAM_INT, 'User id (optional), default is current user.', VALUE_DEFAULT, 0),
 232                  'returncontents' => new external_value(PARAM_BOOL, 'Whether to return the block contents.', VALUE_DEFAULT, false),
 233                  'mypage' => new external_value(PARAM_TEXT, 'What my page to return blocks of', VALUE_DEFAULT, MY_PAGE_DEFAULT),
 234              )
 235          );
 236      }
 237  
 238      /**
 239       * Returns blocks information for the given user dashboard.
 240       *
 241       * @param int $userid The user id to retrieve the blocks from, optional, default is to current user.
 242       * @param bool $returncontents Whether to return the block contents
 243       * @param string $mypage The page to get blocks of within my
 244       * @return array Blocks list and possible warnings
 245       * @throws moodle_exception
 246       * @since Moodle 3.6
 247       */
 248      public static function get_dashboard_blocks($userid = 0, $returncontents = false, $mypage = MY_PAGE_DEFAULT) {
 249          global $CFG, $USER, $PAGE;
 250  
 251          require_once($CFG->dirroot . '/my/lib.php');
 252  
 253          $warnings = array();
 254          $params = self::validate_parameters(self::get_dashboard_blocks_parameters(),
 255              ['userid' => $userid, 'returncontents' => $returncontents, 'mypage' => $mypage]);
 256  
 257          $userid = $params['userid'];
 258          if (empty($userid)) {
 259              $userid = $USER->id;
 260          }
 261  
 262          if ($USER->id != $userid) {
 263              // We must check if the current user can view other users dashboard.
 264              require_capability('moodle/site:config', context_system::instance());
 265              $user = core_user::get_user($userid, '*', MUST_EXIST);
 266              core_user::require_active_user($user);
 267          }
 268  
 269          $context = context_user::instance($userid);;
 270          self::validate_context($context);
 271  
 272          $currentpage = null;
 273          if ($params['mypage'] === MY_PAGE_DEFAULT) {
 274              $currentpage = my_get_page($userid);
 275          } else if ($params['mypage'] === MY_PAGE_COURSES) {
 276              $currentpage = my_get_page($userid, MY_PAGE_PUBLIC, MY_PAGE_COURSES);
 277          }
 278  
 279          if (!$currentpage) {
 280              throw new moodle_exception('mymoodlesetup');
 281          }
 282  
 283          $PAGE->set_context($context);
 284          $PAGE->set_pagelayout('mydashboard');
 285          $PAGE->set_pagetype('my-index');
 286          $PAGE->blocks->add_region('content');   // Need to add this special regition to retrieve the central blocks.
 287          $PAGE->set_subpage($currentpage->id);
 288  
 289          // Load the block instances in the current $PAGE for all the regions.
 290          $returninvisible = has_capability('moodle/my:manageblocks', $context) ? true : false;
 291          $allblocks = self::get_all_current_page_blocks($returninvisible, $params['returncontents']);
 292  
 293          return array(
 294              'blocks' => $allblocks,
 295              'warnings' => $warnings
 296          );
 297      }
 298  
 299      /**
 300       * Returns description of get_dashboard_blocks result values.
 301       *
 302       * @return external_single_structure
 303       * @since Moodle 3.6
 304       */
 305      public static function get_dashboard_blocks_returns() {
 306  
 307          return new external_single_structure(
 308              array(
 309                  'blocks' => new external_multiple_structure(self::get_block_structure(), 'List of blocks in the dashboard.'),
 310                  'warnings'  => new external_warnings(),
 311              )
 312          );
 313      }
 314  }