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