Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
   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   * Utility class for browsing of content bank files.
  19   *
  20   * @package    repository_contentbank
  21   * @copyright  2020 Mihail Geshoski <mihail@moodle.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace repository_contentbank\browser;
  26  
  27  /**
  28   * Base class for the content bank browsers.
  29   *
  30   * @package    repository_contentbank
  31   * @copyright  2020 Mihail Geshoski <mihail@moodle.com>
  32   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33   */
  34  abstract class contentbank_browser {
  35  
  36      /** @var \context The current context. */
  37      protected $context;
  38  
  39      /**
  40       * Get all content nodes in the current context which can be viewed/accessed by the user.
  41       *
  42       * @return array[] The array containing all nodes which can be viewed/accessed by the user in the current context
  43       */
  44      public function get_content(): array {
  45          return array_merge($this->get_context_folders(), $this->get_contentbank_content());
  46      }
  47  
  48      /**
  49       * Generate the full navigation to the current node.
  50       *
  51       * @return array[] The array containing the path to each node in the navigation.
  52       *                 Each navigation node is an array with keys: name, path.
  53       */
  54      public function get_navigation(): array {
  55          // Get the current navigation node.
  56          $currentnavigationnode = \repository_contentbank\helper::create_navigation_node($this->context);
  57          $navigationnodes = [$currentnavigationnode];
  58          // Get the parent content bank browser.
  59          $parent = $this->get_parent();
  60          // Prepend parent navigation node in the navigation nodes array until there is no existing parent.
  61          while ($parent !== null) {
  62              $parentnavigationnode = \repository_contentbank\helper::create_navigation_node($parent->context);
  63              array_unshift($navigationnodes, $parentnavigationnode);
  64              $parent = $parent->get_parent();
  65          }
  66          return $navigationnodes;
  67      }
  68  
  69      /**
  70       * The required condition to enable the user to view/access the content bank content in this context.
  71       *
  72       * @return bool Whether the user can view/access the content bank content in the context
  73       */
  74      abstract public function can_access_content(): bool;
  75  
  76      /**
  77       * Define the allowed child context levels.
  78       *
  79       * @return int[] The array containing the relevant child context levels
  80       */
  81      abstract protected function allowed_child_context_levels(): array;
  82  
  83      /**
  84       * Get the relevant child contexts.
  85       *
  86       * @return \context[] The array containing the relevant, next-level children contexts
  87       */
  88      protected function get_child_contexts(): array {
  89          global $DB;
  90  
  91          if (empty($allowedcontextlevels = $this->allowed_child_context_levels())) {
  92              // Early return if there aren't any defined child context levels.
  93              return [];
  94          }
  95  
  96          list($contextlevelsql, $params) = $DB->get_in_or_equal($allowedcontextlevels, SQL_PARAMS_NAMED);
  97          $pathsql = $DB->sql_like('path', ':path', false, false);
  98  
  99          $select = "contextlevel {$contextlevelsql}
 100                     AND {$pathsql}
 101                     AND depth = :depth";
 102  
 103          $params['path'] = "{$this->context->path}/%";
 104          $params['depth'] = $this->context->depth + 1;
 105  
 106          $childcontexts = $DB->get_records_select('context', $select, $params);
 107  
 108          return array_map(function($childcontext) {
 109              return \context::instance_by_id($childcontext->id);
 110          }, $childcontexts);
 111      }
 112  
 113      /**
 114       * Get the content bank browser class of the parent context. Currently used to generate the navigation path.
 115       *
 116       * @return contentbank_browser|null The content bank browser of the parent context
 117       */
 118      private function get_parent(): ?self {
 119          if ($parentcontext = $this->context->get_parent_context()) {
 120              return \repository_contentbank\helper::get_contentbank_browser($parentcontext);
 121          }
 122          return null;
 123      }
 124  
 125      /**
 126       * Generate folder nodes for the relevant child contexts which can be accessed/viewed by the user.
 127       *
 128       * @return array[] The array containing the context folder nodes where each folder node is an array with keys:
 129       *                 title, datemodified, datecreated, path, thumbnail, children.
 130       */
 131      private function get_context_folders(): array {
 132          // Get all relevant child contexts.
 133          $children = $this->get_child_contexts();
 134          // Return all child context folder nodes which can be accessed by the user following the defined conditions
 135          // in can_access_content().
 136          return array_reduce($children, function ($list, $child) {
 137              $browser = \repository_contentbank\helper::get_contentbank_browser($child);
 138              if ($browser->can_access_content()) {
 139                  $name = $child->get_context_name(false);
 140                  $path = base64_encode(json_encode(['contextid' => $child->id]));
 141                  $list[] = \repository_contentbank\helper::create_context_folder_node($name, $path);
 142              }
 143              return $list;
 144          }, []);
 145      }
 146  
 147      /**
 148       * Generate nodes for the content bank content in the current context which can be accessed/viewed by the user.
 149       *
 150       * @return array[] The array containing the content nodes where each content node is an array with keys:
 151       *                 shorttitle, title, datemodified, datecreated, author, license, isref, source, icon, thumbnail.
 152       */
 153      private function get_contentbank_content(): array {
 154          $cb = new \core_contentbank\contentbank();
 155          // Get all content bank files in the current context.
 156          $contents = $cb->search_contents(null, $this->context->id);
 157          // Return all content bank content nodes from the current context which can be accessed by the user following
 158          // the defined conditions in can_access_content().
 159          return array_reduce($contents, function($list, $content) {
 160              if ($this->can_access_content() &&
 161                      $contentnode = \repository_contentbank\helper::create_contentbank_content_node($content)) {
 162                  $list[] = $contentnode;
 163              }
 164              return $list;
 165          }, []);
 166      }
 167  }