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  /**
  18   * Defines classes used for plugin info.
  19   *
  20   * @package    core
  21   * @copyright  2016 Marina Glancy
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  namespace core\plugininfo;
  25  
  26  /**
  27   * Class for media plugins
  28   *
  29   * @package    core
  30   * @copyright  2016 Marina Glancy
  31   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  32   */
  33  class media extends base {
  34  
  35      public static function plugintype_supports_disabling(): bool {
  36          return true;
  37      }
  38  
  39      public function is_uninstall_allowed() {
  40          return true;
  41      }
  42  
  43      /**
  44       * Get the name for the settings section.
  45       *
  46       * @return string
  47       */
  48      public function get_settings_section_name() {
  49          return 'mediasetting' . $this->name;
  50      }
  51  
  52      /**
  53       * Load the global settings for a particular availability plugin (if there are any)
  54       *
  55       * @param \part_of_admin_tree $adminroot
  56       * @param string $parentnodename
  57       * @param bool $hassiteconfig
  58       */
  59      public function load_settings(\part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) {
  60          global $CFG, $USER, $DB, $OUTPUT, $PAGE; // In case settings.php wants to refer to them.
  61          /** @var \admin_root $ADMIN */
  62          $ADMIN = $adminroot; // May be used in settings.php.
  63          $plugininfo = $this; // Also can be used inside settings.php
  64          $availability = $this; // Also to be used inside settings.php.
  65  
  66          if (!$this->is_installed_and_upgraded()) {
  67              return;
  68          }
  69  
  70          if (!$hassiteconfig) {
  71              return;
  72          }
  73  
  74          $section = $this->get_settings_section_name();
  75  
  76          $settings = null;
  77          if (file_exists($this->full_path('settings.php'))) {
  78              $settings = new \admin_settingpage($section, $this->displayname, 'moodle/site:config', $this->is_enabled() === false);
  79              include($this->full_path('settings.php')); // This may also set $settings to null.
  80          }
  81          if ($settings) {
  82              $ADMIN->add($parentnodename, $settings);
  83          }
  84      }
  85  
  86      /**
  87       * Return URL used for management of plugins of this type.
  88       * @return \moodle_url
  89       */
  90      public static function get_manage_url() {
  91          return new \moodle_url('/admin/settings.php', array('section' => 'managemediaplayers'));
  92      }
  93  
  94      public static function get_enabled_plugins() {
  95          global $CFG;
  96  
  97          $order = (!empty($CFG->media_plugins_sortorder)) ? explode(',', $CFG->media_plugins_sortorder) : [];
  98          if ($order) {
  99              $plugins = \core_plugin_manager::instance()->get_installed_plugins('media');
 100              $order = array_intersect($order, array_keys($plugins));
 101          }
 102          return array_combine($order, $order);
 103      }
 104  
 105      public static function enable_plugin(string $pluginname, int $enabled): bool {
 106          global $CFG;
 107  
 108          $haschanged = false;
 109          $plugins = [];
 110          if (!empty($CFG->media_plugins_sortorder)) {
 111              $plugins = explode(',', $CFG->media_plugins_sortorder);
 112          }
 113          // Only set visibility if it's different from the current value.
 114          if ($enabled && !in_array($pluginname, $plugins)) {
 115              // Enable media plugin.
 116  
 117              /** @var \core\plugininfo\media[] $pluginsbytype */
 118              $pluginsbytype = \core_plugin_manager::instance()->get_plugins_of_type('media');
 119              if (!array_key_exists($pluginname, $pluginsbytype)) {
 120                  // Can not be enabled.
 121                  return false;
 122              }
 123  
 124              $rank = $pluginsbytype[$pluginname]->get_rank();
 125              $position = 0;
 126              // Insert before the first enabled plugin which default rank is smaller than the default rank of this one.
 127              foreach ($plugins as $playername) {
 128                  if (($player = $pluginsbytype[$playername]) && ($rank > $player->get_rank())) {
 129                      break;
 130                  }
 131                  $position++;
 132              }
 133              array_splice($plugins, $position, 0, [$pluginname]);
 134              $haschanged = true;
 135          } else if (!$enabled && in_array($pluginname, $plugins)) {
 136              // Disable media plugin.
 137              $key = array_search($pluginname, $plugins);
 138              unset($plugins[$key]);
 139              $haschanged = true;
 140          }
 141  
 142          if ($haschanged) {
 143              add_to_config_log('media_plugins_sortorder', !$enabled, $enabled, $pluginname);
 144              self::set_enabled_plugins($plugins);
 145          }
 146  
 147          return $haschanged;
 148      }
 149  
 150      /**
 151       * Sets the current plugin as enabled or disabled
 152       * When enabling tries to guess the sortorder based on default rank returned by the plugin.
 153       * @param bool $newstate
 154       */
 155      public function set_enabled($newstate = true) {
 156          self::enable_plugin($this->name, $newstate);
 157      }
 158  
 159      /**
 160       * Set the list of enabled media players in the specified sort order
 161       * To be used when changing settings or in unit tests
 162       * @param string|array $list list of plugin names without frankenstyle prefix - comma-separated string or an array
 163       */
 164      public static function set_enabled_plugins($list) {
 165          if (empty($list)) {
 166              $list = [];
 167          } else if (!is_array($list)) {
 168              $list = explode(',', $list);
 169          }
 170          if ($list) {
 171              $plugins = \core_plugin_manager::instance()->get_installed_plugins('media');
 172              $list = array_intersect($list, array_keys($plugins));
 173          }
 174          set_config('media_plugins_sortorder', join(',', $list));
 175          \core_plugin_manager::reset_caches();
 176          \core_media_manager::reset_caches();
 177      }
 178  
 179      /**
 180       * Returns the default rank of this plugin for default sort order
 181       * @return int
 182       */
 183      public function get_rank() {
 184          $classname = '\media_'.$this->name.'_plugin';
 185          if (class_exists($classname)) {
 186              $object = new $classname();
 187              return $object->get_rank();
 188          }
 189          return 0;
 190      }
 191  
 192      /**
 193       * Returns human-readable string of supported file/link types for the "Manage media players" page
 194       * @param array $extensions
 195       * @return string
 196       */
 197      public function supports(&$extensions) {
 198          $classname = '\media_'.$this->name.'_plugin';
 199          if (class_exists($classname)) {
 200              $object = new $classname();
 201              $result = $object->supports($extensions);
 202              foreach ($object->get_supported_extensions() as $ext) {
 203                  $extensions[$ext] = $ext;
 204              }
 205              return $result;
 206          }
 207          return '';
 208      }
 209  
 210      public static function plugintype_supports_ordering(): bool {
 211          return true;
 212      }
 213  
 214      // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
 215      public static function get_sorted_plugins(bool $enabledonly = false): ?array {
 216          $pluginmanager = \core_plugin_manager::instance();
 217  
 218          $plugins = $pluginmanager->get_plugins_of_type('media');
 219          $enabledplugins = $pluginmanager->get_enabled_plugins('media');
 220  
 221          // Sort plugins so enabled plugins are displayed first and all others are displayed in the end sorted by rank.
 222          \core_collator::asort_objects_by_method($plugins, 'get_rank', \core_collator::SORT_NUMERIC);
 223  
 224          $order = array_values($enabledplugins);
 225          if (!$enabledonly) {
 226              $order = array_merge($order, array_diff(array_reverse(array_keys($plugins)), $order));
 227          }
 228  
 229          $sortedplugins = [];
 230          foreach ($order as $name) {
 231              $sortedplugins[$name] = $plugins[$name];
 232          }
 233  
 234          return $sortedplugins;
 235      }
 236  
 237      public static function change_plugin_order(string $pluginname, int $direction): bool {
 238          $activeeditors = array_keys(self::get_sorted_plugins(true));
 239          $key = array_search($pluginname, $activeeditors);
 240          [$media] = explode('_', $pluginname, 2);
 241  
 242          if ($key === false) {
 243              return false;
 244          }
 245  
 246          $sortorder = array_values(self::get_enabled_plugins());
 247  
 248          if ($direction === self::MOVE_DOWN) {
 249              // Move down the list.
 250              if ((($pos = array_search($media, $sortorder)) !== false) && ($pos < count($sortorder) - 1)) {
 251                  $tmp = $sortorder[$pos + 1];
 252                  $sortorder[$pos + 1] = $sortorder[$pos];
 253                  $sortorder[$pos] = $tmp;
 254                  self::set_enabled_plugins($sortorder);
 255  
 256                  return true;
 257              }
 258          } else if ($direction === self::MOVE_UP) {
 259              if (($pos = array_search($media, $sortorder)) > 0) {
 260                  $tmp = $sortorder[$pos - 1];
 261                  $sortorder[$pos - 1] = $sortorder[$pos];
 262                  $sortorder[$pos] = $tmp;
 263                  self::set_enabled_plugins($sortorder);
 264  
 265                  return true;
 266              }
 267          }
 268  
 269          return false;
 270      }
 271  }