[ Index ] |
PHP Cross Reference of moodle-2.8 |
[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 <[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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |