[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/classes/plugininfo/ -> base.php (source)

   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  2011 David Mudrak <[email protected]>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  namespace core\plugininfo;
  25  
  26  use core_component, core_plugin_manager, moodle_url, coding_exception;
  27  
  28  defined('MOODLE_INTERNAL') || die();
  29  
  30  
  31  /**
  32   * Base class providing access to the information about a plugin
  33   *
  34   * @property-read string component the component name, type_name
  35   */
  36  abstract class base {
  37  
  38      /** @var string the plugintype name, eg. mod, auth or workshopform */
  39      public $type;
  40      /** @var string full path to the location of all the plugins of this type */
  41      public $typerootdir;
  42      /** @var string the plugin name, eg. assignment, ldap */
  43      public $name;
  44      /** @var string the localized plugin name */
  45      public $displayname;
  46      /** @var string the plugin source, one of core_plugin_manager::PLUGIN_SOURCE_xxx constants */
  47      public $source;
  48      /** @var string fullpath to the location of this plugin */
  49      public $rootdir;
  50      /** @var int|string the version of the plugin's source code */
  51      public $versiondisk;
  52      /** @var int|string the version of the installed plugin */
  53      public $versiondb;
  54      /** @var int|float|string required version of Moodle core  */
  55      public $versionrequires;
  56      /** @var mixed human-readable release information */
  57      public $release;
  58      /** @var array other plugins that this one depends on, lazy-loaded by {@link get_other_required_plugins()} */
  59      public $dependencies;
  60      /** @var int number of instances of the plugin - not supported yet */
  61      public $instances;
  62      /** @var int order of the plugin among other plugins of the same type - not supported yet */
  63      public $sortorder;
  64      /** @var array|null array of {@link \core\update\info} for this plugin */
  65      public $availableupdates;
  66  
  67      /**
  68       * Finds all enabled plugins, the result may include missing plugins.
  69       * @return array|null of enabled plugins $pluginname=>$pluginname, null means unknown
  70       */
  71      public static function get_enabled_plugins() {
  72          return null;
  73      }
  74  
  75      /**
  76       * Gathers and returns the information about all plugins of the given type,
  77       * either on disk or previously installed.
  78       *
  79       * @param string $type the name of the plugintype, eg. mod, auth or workshopform
  80       * @param string $typerootdir full path to the location of the plugin dir
  81       * @param string $typeclass the name of the actually called class
  82       * @return array of plugintype classes, indexed by the plugin name
  83       */
  84      public static function get_plugins($type, $typerootdir, $typeclass) {
  85          // Get the information about plugins at the disk.
  86          $plugins = core_component::get_plugin_list($type);
  87          $return = array();
  88          foreach ($plugins as $pluginname => $pluginrootdir) {
  89              $return[$pluginname] = self::make_plugin_instance($type, $typerootdir,
  90                  $pluginname, $pluginrootdir, $typeclass);
  91          }
  92  
  93          // Fetch missing incorrectly uninstalled plugins.
  94          $manager = core_plugin_manager::instance();
  95          $plugins = $manager->get_installed_plugins($type);
  96  
  97          foreach ($plugins as $name => $version) {
  98              if (isset($return[$name])) {
  99                  continue;
 100              }
 101              $plugin              = new $typeclass();
 102              $plugin->type        = $type;
 103              $plugin->typerootdir = $typerootdir;
 104              $plugin->name        = $name;
 105              $plugin->rootdir     = null;
 106              $plugin->displayname = $name;
 107              $plugin->versiondb   = $version;
 108              $plugin->init_is_standard();
 109  
 110              $return[$name] = $plugin;
 111          }
 112  
 113          return $return;
 114      }
 115  
 116      /**
 117       * Makes a new instance of the plugininfo class
 118       *
 119       * @param string $type the plugin type, eg. 'mod'
 120       * @param string $typerootdir full path to the location of all the plugins of this type
 121       * @param string $name the plugin name, eg. 'workshop'
 122       * @param string $namerootdir full path to the location of the plugin
 123       * @param string $typeclass the name of class that holds the info about the plugin
 124       * @return base the instance of $typeclass
 125       */
 126      protected static function make_plugin_instance($type, $typerootdir, $name, $namerootdir, $typeclass) {
 127          $plugin              = new $typeclass();
 128          $plugin->type        = $type;
 129          $plugin->typerootdir = $typerootdir;
 130          $plugin->name        = $name;
 131          $plugin->rootdir     = $namerootdir;
 132  
 133          $plugin->init_display_name();
 134          $plugin->load_disk_version();
 135          $plugin->load_db_version();
 136          $plugin->init_is_standard();
 137  
 138          return $plugin;
 139      }
 140  
 141      /**
 142       * Is this plugin already installed and updated?
 143       * @return bool true if plugin installed and upgraded.
 144       */
 145      public function is_installed_and_upgraded() {
 146          if (!$this->rootdir) {
 147              return false;
 148          }
 149          if ($this->versiondb === null and $this->versiondisk === null) {
 150              // There is no version.php or version info inside,
 151              // for now let's pretend it is ok.
 152              // TODO: return false once we require version in each plugin.
 153              return true;
 154          }
 155  
 156          return ((float)$this->versiondb === (float)$this->versiondisk);
 157      }
 158  
 159      /**
 160       * Sets {@link $displayname} property to a localized name of the plugin
 161       */
 162      public function init_display_name() {
 163          if (!get_string_manager()->string_exists('pluginname', $this->component)) {
 164              $this->displayname = '[pluginname,' . $this->component . ']';
 165          } else {
 166              $this->displayname = get_string('pluginname', $this->component);
 167          }
 168      }
 169  
 170      /**
 171       * Magic method getter, redirects to read only values.
 172       *
 173       * @param string $name
 174       * @return mixed
 175       */
 176      public function __get($name) {
 177          switch ($name) {
 178              case 'component': return $this->type . '_' . $this->name;
 179  
 180              default:
 181                  debugging('Invalid plugin property accessed! '.$name);
 182                  return null;
 183          }
 184      }
 185  
 186      /**
 187       * Return the full path name of a file within the plugin.
 188       *
 189       * No check is made to see if the file exists.
 190       *
 191       * @param string $relativepath e.g. 'version.php'.
 192       * @return string e.g. $CFG->dirroot . '/mod/quiz/version.php'.
 193       */
 194      public function full_path($relativepath) {
 195          if (empty($this->rootdir)) {
 196              return '';
 197          }
 198          return $this->rootdir . '/' . $relativepath;
 199      }
 200  
 201      /**
 202       * Sets {@link $versiondisk} property to a numerical value representing the
 203       * version of the plugin's source code.
 204       *
 205       * If the value is null after calling this method, either the plugin
 206       * does not use versioning (typically does not have any database
 207       * data) or is missing from disk.
 208       */
 209      public function load_disk_version() {
 210          $versions = core_plugin_manager::instance()->get_present_plugins($this->type);
 211  
 212          $this->versiondisk = null;
 213          $this->versionrequires = null;
 214          $this->dependencies = array();
 215  
 216          if (!isset($versions[$this->name])) {
 217              return;
 218          }
 219  
 220          $plugin = $versions[$this->name];
 221  
 222          if (isset($plugin->version)) {
 223              $this->versiondisk = $plugin->version;
 224          }
 225          if (isset($plugin->requires)) {
 226              $this->versionrequires = $plugin->requires;
 227          }
 228          if (isset($plugin->release)) {
 229              $this->release = $plugin->release;
 230          }
 231          if (isset($plugin->dependencies)) {
 232              $this->dependencies = $plugin->dependencies;
 233          }
 234      }
 235  
 236      /**
 237       * Get the list of other plugins that this plugin requires to be installed.
 238       *
 239       * @return array with keys the frankenstyle plugin name, and values either
 240       *      a version string (like '2011101700') or the constant ANY_VERSION.
 241       */
 242      public function get_other_required_plugins() {
 243          if (is_null($this->dependencies)) {
 244              $this->load_disk_version();
 245          }
 246          return $this->dependencies;
 247      }
 248  
 249      /**
 250       * Is this is a subplugin?
 251       *
 252       * @return boolean
 253       */
 254      public function is_subplugin() {
 255          return ($this->get_parent_plugin() !== false);
 256      }
 257  
 258      /**
 259       * If I am a subplugin, return the name of my parent plugin.
 260       *
 261       * @return string|bool false if not a subplugin, name of the parent otherwise
 262       */
 263      public function get_parent_plugin() {
 264          return $this->get_plugin_manager()->get_parent_of_subplugin($this->type);
 265      }
 266  
 267      /**
 268       * Sets {@link $versiondb} property to a numerical value representing the
 269       * currently installed version of the plugin.
 270       *
 271       * If the value is null after calling this method, either the plugin
 272       * does not use versioning (typically does not have any database
 273       * data) or has not been installed yet.
 274       */
 275      public function load_db_version() {
 276          $versions = core_plugin_manager::instance()->get_installed_plugins($this->type);
 277  
 278          if (isset($versions[$this->name])) {
 279              $this->versiondb = $versions[$this->name];
 280          } else {
 281              $this->versiondb = null;
 282          }
 283      }
 284  
 285      /**
 286       * Sets {@link $source} property to one of core_plugin_manager::PLUGIN_SOURCE_xxx
 287       * constants.
 288       *
 289       * If the property's value is null after calling this method, then
 290       * the type of the plugin has not been recognized and you should throw
 291       * an exception.
 292       */
 293      public function init_is_standard() {
 294  
 295          $standard = core_plugin_manager::standard_plugins_list($this->type);
 296  
 297          if ($standard !== false) {
 298              $standard = array_flip($standard);
 299              if (isset($standard[$this->name])) {
 300                  $this->source = core_plugin_manager::PLUGIN_SOURCE_STANDARD;
 301              } else if (!is_null($this->versiondb) and is_null($this->versiondisk)
 302                  and core_plugin_manager::is_deleted_standard_plugin($this->type, $this->name)) {
 303                  $this->source = core_plugin_manager::PLUGIN_SOURCE_STANDARD; // To be deleted.
 304              } else {
 305                  $this->source = core_plugin_manager::PLUGIN_SOURCE_EXTENSION;
 306              }
 307          }
 308      }
 309  
 310      /**
 311       * Returns true if the plugin is shipped with the official distribution
 312       * of the current Moodle version, false otherwise.
 313       *
 314       * @return bool
 315       */
 316      public function is_standard() {
 317          return $this->source === core_plugin_manager::PLUGIN_SOURCE_STANDARD;
 318      }
 319  
 320      /**
 321       * Returns true if the the given Moodle version is enough to run this plugin
 322       *
 323       * @param string|int|double $moodleversion
 324       * @return bool
 325       */
 326      public function is_core_dependency_satisfied($moodleversion) {
 327  
 328          if (empty($this->versionrequires)) {
 329              return true;
 330  
 331          } else {
 332              return (double)$this->versionrequires <= (double)$moodleversion;
 333          }
 334      }
 335  
 336      /**
 337       * Returns the status of the plugin
 338       *
 339       * @return string one of core_plugin_manager::PLUGIN_STATUS_xxx constants
 340       */
 341      public function get_status() {
 342  
 343          if (is_null($this->versiondb) and is_null($this->versiondisk)) {
 344              return core_plugin_manager::PLUGIN_STATUS_NODB;
 345  
 346          } else if (is_null($this->versiondb) and !is_null($this->versiondisk)) {
 347              return core_plugin_manager::PLUGIN_STATUS_NEW;
 348  
 349          } else if (!is_null($this->versiondb) and is_null($this->versiondisk)) {
 350              if (core_plugin_manager::is_deleted_standard_plugin($this->type, $this->name)) {
 351                  return core_plugin_manager::PLUGIN_STATUS_DELETE;
 352              } else {
 353                  return core_plugin_manager::PLUGIN_STATUS_MISSING;
 354              }
 355  
 356          } else if ((float)$this->versiondb === (float)$this->versiondisk) {
 357              // Note: the float comparison should work fine here
 358              //       because there are no arithmetic operations with the numbers.
 359              return core_plugin_manager::PLUGIN_STATUS_UPTODATE;
 360  
 361          } else if ($this->versiondb < $this->versiondisk) {
 362              return core_plugin_manager::PLUGIN_STATUS_UPGRADE;
 363  
 364          } else if ($this->versiondb > $this->versiondisk) {
 365              return core_plugin_manager::PLUGIN_STATUS_DOWNGRADE;
 366  
 367          } else {
 368              // $version = pi(); and similar funny jokes - hopefully Donald E. Knuth will never contribute to Moodle ;-)
 369              throw new coding_exception('Unable to determine plugin state, check the plugin versions');
 370          }
 371      }
 372  
 373      /**
 374       * Returns the information about plugin availability
 375       *
 376       * True means that the plugin is enabled. False means that the plugin is
 377       * disabled. Null means that the information is not available, or the
 378       * plugin does not support configurable availability or the availability
 379       * can not be changed.
 380       *
 381       * @return null|bool
 382       */
 383      public function is_enabled() {
 384          if (!$this->rootdir) {
 385              // Plugin missing.
 386              return false;
 387          }
 388  
 389          $enabled = core_plugin_manager::instance()->get_enabled_plugins($this->type);
 390  
 391          if (!is_array($enabled)) {
 392              return null;
 393          }
 394  
 395          return isset($enabled[$this->name]);
 396      }
 397  
 398      /**
 399       * Populates the property {@link $availableupdates} with the information provided by
 400       * available update checker
 401       *
 402       * @param \core\update\checker $provider the class providing the available update info
 403       */
 404      public function check_available_updates(\core\update\checker $provider) {
 405          global $CFG;
 406  
 407          if (isset($CFG->updateminmaturity)) {
 408              $minmaturity = $CFG->updateminmaturity;
 409          } else {
 410              // This can happen during the very first upgrade to 2.3 .
 411              $minmaturity = MATURITY_STABLE;
 412          }
 413  
 414          $this->availableupdates = $provider->get_update_info($this->component,
 415              array('minmaturity' => $minmaturity));
 416      }
 417  
 418      /**
 419       * If there are updates for this plugin available, returns them.
 420       *
 421       * Returns array of {@link \core\update\info} objects, if some update
 422       * is available. Returns null if there is no update available or if the update
 423       * availability is unknown.
 424       *
 425       * @return array|null
 426       */
 427      public function available_updates() {
 428  
 429          if (empty($this->availableupdates) or !is_array($this->availableupdates)) {
 430              return null;
 431          }
 432  
 433          $updates = array();
 434  
 435          foreach ($this->availableupdates as $availableupdate) {
 436              if ($availableupdate->version > $this->versiondisk) {
 437                  $updates[] = $availableupdate;
 438              }
 439          }
 440  
 441          if (empty($updates)) {
 442              return null;
 443          }
 444  
 445          return $updates;
 446      }
 447  
 448      /**
 449       * Returns the node name used in admin settings menu for this plugin settings (if applicable)
 450       *
 451       * @return null|string node name or null if plugin does not create settings node (default)
 452       */
 453      public function get_settings_section_name() {
 454          return null;
 455      }
 456  
 457      /**
 458       * Returns the URL of the plugin settings screen
 459       *
 460       * Null value means that the plugin either does not have the settings screen
 461       * or its location is not available via this library.
 462       *
 463       * @return null|moodle_url
 464       */
 465      public function get_settings_url() {
 466          $section = $this->get_settings_section_name();
 467          if ($section === null) {
 468              return null;
 469          }
 470          $settings = admin_get_root()->locate($section);
 471          if ($settings && $settings instanceof \admin_settingpage) {
 472              return new moodle_url('/admin/settings.php', array('section' => $section));
 473          } else if ($settings && $settings instanceof \admin_externalpage) {
 474              return new moodle_url($settings->url);
 475          } else {
 476              return null;
 477          }
 478      }
 479  
 480      /**
 481       * Loads plugin settings to the settings tree
 482       *
 483       * This function usually includes settings.php file in plugins folder.
 484       * Alternatively it can create a link to some settings page (instance of admin_externalpage)
 485       *
 486       * @param \part_of_admin_tree $adminroot
 487       * @param string $parentnodename
 488       * @param bool $hassiteconfig whether the current user has moodle/site:config capability
 489       */
 490      public function load_settings(\part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) {
 491      }
 492  
 493      /**
 494       * Should there be a way to uninstall the plugin via the administration UI.
 495       *
 496       * By default uninstallation is not allowed, plugin developers must enable it explicitly!
 497       *
 498       * @return bool
 499       */
 500      public function is_uninstall_allowed() {
 501          return false;
 502      }
 503  
 504      /**
 505       * Optional extra warning before uninstallation, for example number of uses in courses.
 506       *
 507       * @return string
 508       */
 509      public function get_uninstall_extra_warning() {
 510          return '';
 511      }
 512  
 513      /**
 514       * Pre-uninstall hook.
 515       *
 516       * This is intended for disabling of plugin, some DB table purging, etc.
 517       *
 518       * NOTE: to be called from uninstall_plugin() only.
 519       * @private
 520       */
 521      public function uninstall_cleanup() {
 522          // Override when extending class,
 523          // do not forget to call parent::pre_uninstall_cleanup() at the end.
 524      }
 525  
 526      /**
 527       * Returns relative directory of the plugin with heading '/'
 528       *
 529       * @return string
 530       */
 531      public function get_dir() {
 532          global $CFG;
 533  
 534          return substr($this->rootdir, strlen($CFG->dirroot));
 535      }
 536  
 537      /**
 538       * Hook method to implement certain steps when uninstalling the plugin.
 539       *
 540       * This hook is called by {@link core_plugin_manager::uninstall_plugin()} so
 541       * it is basically usable only for those plugin types that use the default
 542       * uninstall tool provided by {@link self::get_default_uninstall_url()}.
 543       *
 544       * @param \progress_trace $progress traces the process
 545       * @return bool true on success, false on failure
 546       */
 547      public function uninstall(\progress_trace $progress) {
 548          return true;
 549      }
 550  
 551      /**
 552       * Where should we return after plugin of this type is uninstalled?
 553       * @param string $return
 554       * @return moodle_url
 555       */
 556      public function get_return_url_after_uninstall($return) {
 557          if ($return === 'manage') {
 558              if ($url = $this->get_manage_url()) {
 559                  return $url;
 560              }
 561          }
 562          return new moodle_url('/admin/plugins.php#plugin_type_cell_'.$this->type);
 563      }
 564  
 565      /**
 566       * Return URL used for management of plugins of this type.
 567       * @return moodle_url
 568       */
 569      public static function get_manage_url() {
 570          return null;
 571      }
 572  
 573      /**
 574       * Returns URL to a script that handles common plugin uninstall procedure.
 575       *
 576       * This URL is intended for all plugin uninstallations.
 577       *
 578       * @param string $return either 'overview' or 'manage'
 579       * @return moodle_url
 580       */
 581      public final function get_default_uninstall_url($return = 'overview') {
 582          return new moodle_url('/admin/plugins.php', array(
 583              'sesskey' => sesskey(),
 584              'uninstall' => $this->component,
 585              'confirm' => 0,
 586              'return' => $return,
 587          ));
 588      }
 589  
 590      /**
 591       * Provides access to the core_plugin_manager singleton.
 592       *
 593       * @return core_plugin_manager
 594       */
 595      protected function get_plugin_manager() {
 596          return core_plugin_manager::instance();
 597      }
 598  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1