|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00030 defined('MOODLE_INTERNAL') || die(); 00031 00035 class plugin_manager { 00036 00038 const PLUGIN_SOURCE_STANDARD = 'std'; 00040 const PLUGIN_SOURCE_EXTENSION = 'ext'; 00041 00043 const PLUGIN_STATUS_NODB = 'nodb'; 00045 const PLUGIN_STATUS_UPTODATE = 'uptodate'; 00047 const PLUGIN_STATUS_NEW = 'new'; 00049 const PLUGIN_STATUS_UPGRADE = 'upgrade'; 00051 const PLUGIN_STATUS_DELETE = 'delete'; 00053 const PLUGIN_STATUS_DOWNGRADE = 'downgrade'; 00055 const PLUGIN_STATUS_MISSING = 'missing'; 00056 00058 protected static $singletoninstance; 00060 protected $pluginsinfo = null; 00062 protected $subpluginsinfo = null; 00063 00069 protected function __construct() { 00070 $this->get_plugins(true); 00071 } 00072 00076 protected function __clone() { 00077 } 00078 00084 public static function instance() { 00085 global $CFG; 00086 00087 if (is_null(self::$singletoninstance)) { 00088 self::$singletoninstance = new self(); 00089 } 00090 return self::$singletoninstance; 00091 } 00092 00101 public function get_plugins($disablecache=false) { 00102 00103 if ($disablecache or is_null($this->pluginsinfo)) { 00104 $this->pluginsinfo = array(); 00105 $plugintypes = get_plugin_types(); 00106 foreach ($plugintypes as $plugintype => $plugintyperootdir) { 00107 if (in_array($plugintype, array('base', 'general'))) { 00108 throw new coding_exception('Illegal usage of reserved word for plugin type'); 00109 } 00110 if (class_exists('plugintype_' . $plugintype)) { 00111 $plugintypeclass = 'plugintype_' . $plugintype; 00112 } else { 00113 $plugintypeclass = 'plugintype_general'; 00114 } 00115 if (!in_array('plugin_information', class_implements($plugintypeclass))) { 00116 throw new coding_exception('Class ' . $plugintypeclass . ' must implement plugin_information'); 00117 } 00118 $plugins = call_user_func(array($plugintypeclass, 'get_plugins'), $plugintype, $plugintyperootdir, $plugintypeclass); 00119 $this->pluginsinfo[$plugintype] = $plugins; 00120 } 00121 } 00122 00123 return $this->pluginsinfo; 00124 } 00125 00136 public function get_subplugins($disablecache=false) { 00137 00138 if ($disablecache or is_null($this->subpluginsinfo)) { 00139 $this->subpluginsinfo = array(); 00140 $mods = get_plugin_list('mod'); 00141 foreach ($mods as $mod => $moddir) { 00142 $modsubplugins = array(); 00143 if (file_exists($moddir . '/db/subplugins.php')) { 00144 include($moddir . '/db/subplugins.php'); 00145 foreach ($subplugins as $subplugintype => $subplugintyperootdir) { 00146 $subplugin = new stdClass(); 00147 $subplugin->type = $subplugintype; 00148 $subplugin->typerootdir = $subplugintyperootdir; 00149 $modsubplugins[$subplugintype] = $subplugin; 00150 } 00151 $this->subpluginsinfo['mod_' . $mod] = $modsubplugins; 00152 } 00153 } 00154 } 00155 00156 return $this->subpluginsinfo; 00157 } 00158 00167 public function get_parent_of_subplugin($subplugintype) { 00168 00169 $parent = false; 00170 foreach ($this->get_subplugins() as $pluginname => $subplugintypes) { 00171 if (isset($subplugintypes[$subplugintype])) { 00172 $parent = $pluginname; 00173 break; 00174 } 00175 } 00176 00177 return $parent; 00178 } 00179 00186 public function plugin_name($plugin) { 00187 list($type, $name) = normalize_component($plugin); 00188 return $this->pluginsinfo[$type][$name]->displayname; 00189 } 00190 00201 public function plugintype_name_plural($type) { 00202 00203 if (get_string_manager()->string_exists('type_' . $type . '_plural', 'core_plugin')) { 00204 // for most plugin types, their names are defined in core_plugin lang file 00205 return get_string('type_' . $type . '_plural', 'core_plugin'); 00206 00207 } else if ($parent = $this->get_parent_of_subplugin($type)) { 00208 // if this is a subplugin, try to ask the parent plugin for the name 00209 if (get_string_manager()->string_exists('subplugintype_' . $type . '_plural', $parent)) { 00210 return $this->plugin_name($parent) . ' / ' . get_string('subplugintype_' . $type . '_plural', $parent); 00211 } else { 00212 return $this->plugin_name($parent) . ' / ' . $type; 00213 } 00214 00215 } else { 00216 return $type; 00217 } 00218 } 00219 00224 public function get_plugin_info($component) { 00225 list($type, $name) = normalize_component($component); 00226 $plugins = $this->get_plugins(); 00227 if (isset($plugins[$type][$name])) { 00228 return $plugins[$type][$name]; 00229 } else { 00230 return null; 00231 } 00232 } 00233 00239 public function other_plugins_that_require($component) { 00240 $others = array(); 00241 foreach ($this->get_plugins() as $type => $plugins) { 00242 foreach ($plugins as $plugin) { 00243 $required = $plugin->get_other_required_plugins(); 00244 if (isset($required[$component])) { 00245 $others[] = $plugin->component; 00246 } 00247 } 00248 } 00249 return $others; 00250 } 00251 00257 public function are_dependencies_satisfied($dependencies) { 00258 foreach ($dependencies as $component => $requiredversion) { 00259 $otherplugin = $this->get_plugin_info($component); 00260 if (is_null($otherplugin)) { 00261 return false; 00262 } 00263 00264 if ($requiredversion != ANY_VERSION and $otherplugin->versiondisk < $requiredversion) { 00265 return false; 00266 } 00267 } 00268 00269 return true; 00270 } 00271 00277 public function all_plugins_ok($moodleversion) { 00278 foreach ($this->get_plugins() as $type => $plugins) { 00279 foreach ($plugins as $plugin) { 00280 00281 if (!empty($plugin->versionrequires) && $plugin->versionrequires > $moodleversion) { 00282 return false; 00283 } 00284 00285 if (!$this->are_dependencies_satisfied($plugin->get_other_required_plugins())) { 00286 return false; 00287 } 00288 } 00289 } 00290 00291 return true; 00292 } 00293 00304 public static function is_deleted_standard_plugin($type, $name) { 00305 static $plugins = array( 00306 'block' => array('admin', 'admin_tree', 'loancalc', 'search'), 00307 'filter' => array('mod_data', 'mod_glossary'), 00308 ); 00309 00310 if (!isset($plugins[$type])) { 00311 return false; 00312 } 00313 return in_array($name, $plugins[$type]); 00314 } 00315 00322 public static function standard_plugins_list($type) { 00323 static $standard_plugins = array( 00324 00325 'assignment' => array( 00326 'offline', 'online', 'upload', 'uploadsingle' 00327 ), 00328 00329 'auth' => array( 00330 'cas', 'db', 'email', 'fc', 'imap', 'ldap', 'manual', 'mnet', 00331 'nntp', 'nologin', 'none', 'pam', 'pop3', 'radius', 00332 'shibboleth', 'webservice' 00333 ), 00334 00335 'block' => array( 00336 'activity_modules', 'admin_bookmarks', 'blog_menu', 00337 'blog_recent', 'blog_tags', 'calendar_month', 00338 'calendar_upcoming', 'comments', 'community', 00339 'completionstatus', 'course_list', 'course_overview', 00340 'course_summary', 'feedback', 'glossary_random', 'html', 00341 'login', 'mentees', 'messages', 'mnet_hosts', 'myprofile', 00342 'navigation', 'news_items', 'online_users', 'participants', 00343 'private_files', 'quiz_results', 'recent_activity', 00344 'rss_client', 'search_forums', 'section_links', 00345 'selfcompletion', 'settings', 'site_main_menu', 00346 'social_activities', 'tag_flickr', 'tag_youtube', 'tags' 00347 ), 00348 00349 'coursereport' => array( 00350 //deprecated! 00351 ), 00352 00353 'datafield' => array( 00354 'checkbox', 'date', 'file', 'latlong', 'menu', 'multimenu', 00355 'number', 'picture', 'radiobutton', 'text', 'textarea', 'url' 00356 ), 00357 00358 'datapreset' => array( 00359 'imagegallery' 00360 ), 00361 00362 'editor' => array( 00363 'textarea', 'tinymce' 00364 ), 00365 00366 'enrol' => array( 00367 'authorize', 'category', 'cohort', 'database', 'flatfile', 00368 'guest', 'imsenterprise', 'ldap', 'manual', 'meta', 'mnet', 00369 'paypal', 'self' 00370 ), 00371 00372 'filter' => array( 00373 'activitynames', 'algebra', 'censor', 'emailprotect', 00374 'emoticon', 'mediaplugin', 'multilang', 'tex', 'tidy', 00375 'urltolink', 'data', 'glossary' 00376 ), 00377 00378 'format' => array( 00379 'scorm', 'social', 'topics', 'weeks' 00380 ), 00381 00382 'gradeexport' => array( 00383 'ods', 'txt', 'xls', 'xml' 00384 ), 00385 00386 'gradeimport' => array( 00387 'csv', 'xml' 00388 ), 00389 00390 'gradereport' => array( 00391 'grader', 'outcomes', 'overview', 'user' 00392 ), 00393 00394 'gradingform' => array( 00395 'rubric' 00396 ), 00397 00398 'local' => array( 00399 ), 00400 00401 'message' => array( 00402 'email', 'jabber', 'popup' 00403 ), 00404 00405 'mnetservice' => array( 00406 'enrol' 00407 ), 00408 00409 'mod' => array( 00410 'assignment', 'chat', 'choice', 'data', 'feedback', 'folder', 00411 'forum', 'glossary', 'imscp', 'label', 'lesson', 'lti', 'page', 00412 'quiz', 'resource', 'scorm', 'survey', 'url', 'wiki', 'workshop' 00413 ), 00414 00415 'plagiarism' => array( 00416 ), 00417 00418 'portfolio' => array( 00419 'boxnet', 'download', 'flickr', 'googledocs', 'mahara', 'picasa' 00420 ), 00421 00422 'profilefield' => array( 00423 'checkbox', 'datetime', 'menu', 'text', 'textarea' 00424 ), 00425 00426 'qbehaviour' => array( 00427 'adaptive', 'adaptivenopenalty', 'deferredcbm', 00428 'deferredfeedback', 'immediatecbm', 'immediatefeedback', 00429 'informationitem', 'interactive', 'interactivecountback', 00430 'manualgraded', 'missing' 00431 ), 00432 00433 'qformat' => array( 00434 'aiken', 'blackboard', 'blackboard_six', 'examview', 'gift', 00435 'learnwise', 'missingword', 'multianswer', 'webct', 00436 'xhtml', 'xml' 00437 ), 00438 00439 'qtype' => array( 00440 'calculated', 'calculatedmulti', 'calculatedsimple', 00441 'description', 'essay', 'match', 'missingtype', 'multianswer', 00442 'multichoice', 'numerical', 'random', 'randomsamatch', 00443 'shortanswer', 'truefalse' 00444 ), 00445 00446 'quiz' => array( 00447 'grading', 'overview', 'responses', 'statistics' 00448 ), 00449 00450 'quizaccess' => array( 00451 'delaybetweenattempts', 'ipaddress', 'numattempts', 'openclosedate', 00452 'password', 'safebrowser', 'securewindow', 'timelimit' 00453 ), 00454 00455 'report' => array( 00456 'backups', 'completion', 'configlog', 'courseoverview', 00457 'log', 'loglive', 'outline', 'participation', 'progress', 'questioninstances', 'security', 'stats' 00458 ), 00459 00460 'repository' => array( 00461 'alfresco', 'boxnet', 'coursefiles', 'dropbox', 'filesystem', 00462 'flickr', 'flickr_public', 'googledocs', 'local', 'merlot', 00463 'picasa', 'recent', 's3', 'upload', 'url', 'user', 'webdav', 00464 'wikimedia', 'youtube' 00465 ), 00466 00467 'scormreport' => array( 00468 'basic', 00469 'interactions' 00470 ), 00471 00472 'theme' => array( 00473 'afterburner', 'anomaly', 'arialist', 'base', 'binarius', 00474 'boxxie', 'brick', 'canvas', 'formal_white', 'formfactor', 00475 'fusion', 'leatherbound', 'magazine', 'mymobile', 'nimble', 00476 'nonzero', 'overlay', 'serenity', 'sky_high', 'splash', 00477 'standard', 'standardold' 00478 ), 00479 00480 'tool' => array( 00481 'bloglevelupgrade', 'capability', 'customlang', 'dbtransfer', 'generator', 00482 'health', 'innodb', 'langimport', 'multilangupgrade', 'profiling', 00483 'qeupgradehelper', 'replace', 'spamcleaner', 'timezoneimport', 'unittest', 00484 'uploaduser', 'unsuproles', 'xmldb' 00485 ), 00486 00487 'webservice' => array( 00488 'amf', 'rest', 'soap', 'xmlrpc' 00489 ), 00490 00491 'workshopallocation' => array( 00492 'manual', 'random' 00493 ), 00494 00495 'workshopeval' => array( 00496 'best' 00497 ), 00498 00499 'workshopform' => array( 00500 'accumulative', 'comments', 'numerrors', 'rubric' 00501 ) 00502 ); 00503 00504 if (isset($standard_plugins[$type])) { 00505 return $standard_plugins[$type]; 00506 00507 } else { 00508 return false; 00509 } 00510 } 00511 } 00512 00522 interface plugin_information { 00523 00536 public static function get_plugins($type, $typerootdir, $typeclass); 00537 00543 public function init_display_name(); 00544 00555 public function load_disk_version(); 00556 00567 public function load_db_version(); 00568 00575 public function load_required_main_version(); 00576 00587 public function init_is_standard(); 00588 00595 public function is_standard(); 00596 00602 public function get_status(); 00603 00609 public function get_other_required_plugins(); 00610 00621 public function is_enabled(); 00622 00631 public function get_settings_url(); 00632 00644 public function get_uninstall_url(); 00645 00652 public function get_dir(); 00653 00660 public function full_path($relativepath); 00661 } 00662 00669 abstract class plugintype_base { 00670 00672 public $type; 00674 public $typerootdir; 00676 public $name; 00678 public $displayname; 00680 public $source; 00682 public $rootdir; 00684 public $versiondisk; 00686 public $versiondb; 00688 public $versionrequires; 00691 public $dependencies = null; 00693 public $instances; 00695 public $sortorder; 00696 00700 public static function get_plugins($type, $typerootdir, $typeclass) { 00701 00702 // get the information about plugins at the disk 00703 $plugins = get_plugin_list($type); 00704 $ondisk = array(); 00705 foreach ($plugins as $pluginname => $pluginrootdir) { 00706 $plugin = new $typeclass(); 00707 $plugin->type = $type; 00708 $plugin->typerootdir = $typerootdir; 00709 $plugin->name = $pluginname; 00710 $plugin->rootdir = $pluginrootdir; 00711 00712 $plugin->init_display_name(); 00713 $plugin->load_disk_version(); 00714 $plugin->load_db_version(); 00715 $plugin->load_required_main_version(); 00716 $plugin->init_is_standard(); 00717 00718 $ondisk[$pluginname] = $plugin; 00719 } 00720 return $ondisk; 00721 } 00722 00726 public function init_display_name() { 00727 if (!get_string_manager()->string_exists('pluginname', $this->component)) { 00728 $this->displayname = '[pluginname,' . $this->component . ']'; 00729 } else { 00730 $this->displayname = get_string('pluginname', $this->component); 00731 } 00732 } 00733 00739 public function __get($name) { 00740 switch ($name) { 00741 case 'component': return $this->type . '_' . $this->name; 00742 00743 default: 00744 debugging('Invalid plugin property accessed! '.$name); 00745 return null; 00746 } 00747 } 00748 00752 public function full_path($relativepath) { 00753 if (empty($this->rootdir)) { 00754 return ''; 00755 } 00756 return $this->rootdir . '/' . $relativepath; 00757 } 00758 00763 protected function load_version_php() { 00764 $versionfile = $this->full_path('version.php'); 00765 00766 $plugin = new stdClass(); 00767 if (is_readable($versionfile)) { 00768 include($versionfile); 00769 } 00770 return $plugin; 00771 } 00772 00776 public function load_disk_version() { 00777 $plugin = $this->load_version_php(); 00778 if (isset($plugin->version)) { 00779 $this->versiondisk = $plugin->version; 00780 } 00781 } 00782 00786 public function load_required_main_version() { 00787 $plugin = $this->load_version_php(); 00788 if (isset($plugin->requires)) { 00789 $this->versionrequires = $plugin->requires; 00790 } 00791 } 00792 00797 protected function load_other_required_plugins() { 00798 $plugin = $this->load_version_php(); 00799 if (!empty($plugin->dependencies)) { 00800 $this->dependencies = $plugin->dependencies; 00801 } else { 00802 $this->dependencies = array(); // By default, no dependencies. 00803 } 00804 } 00805 00809 public function get_other_required_plugins() { 00810 if (is_null($this->dependencies)) { 00811 $this->load_other_required_plugins(); 00812 } 00813 return $this->dependencies; 00814 } 00815 00819 public function load_db_version() { 00820 00821 if ($ver = self::get_version_from_config_plugins($this->component)) { 00822 $this->versiondb = $ver; 00823 } 00824 } 00825 00829 public function init_is_standard() { 00830 00831 $standard = plugin_manager::standard_plugins_list($this->type); 00832 00833 if ($standard !== false) { 00834 $standard = array_flip($standard); 00835 if (isset($standard[$this->name])) { 00836 $this->source = plugin_manager::PLUGIN_SOURCE_STANDARD; 00837 } else if (!is_null($this->versiondb) and is_null($this->versiondisk) 00838 and plugin_manager::is_deleted_standard_plugin($this->type, $this->name)) { 00839 $this->source = plugin_manager::PLUGIN_SOURCE_STANDARD; // to be deleted 00840 } else { 00841 $this->source = plugin_manager::PLUGIN_SOURCE_EXTENSION; 00842 } 00843 } 00844 } 00845 00849 public function is_standard() { 00850 return $this->source === plugin_manager::PLUGIN_SOURCE_STANDARD; 00851 } 00852 00856 public function get_status() { 00857 00858 if (is_null($this->versiondb) and is_null($this->versiondisk)) { 00859 return plugin_manager::PLUGIN_STATUS_NODB; 00860 00861 } else if (is_null($this->versiondb) and !is_null($this->versiondisk)) { 00862 return plugin_manager::PLUGIN_STATUS_NEW; 00863 00864 } else if (!is_null($this->versiondb) and is_null($this->versiondisk)) { 00865 if (plugin_manager::is_deleted_standard_plugin($this->type, $this->name)) { 00866 return plugin_manager::PLUGIN_STATUS_DELETE; 00867 } else { 00868 return plugin_manager::PLUGIN_STATUS_MISSING; 00869 } 00870 00871 } else if ((string)$this->versiondb === (string)$this->versiondisk) { 00872 return plugin_manager::PLUGIN_STATUS_UPTODATE; 00873 00874 } else if ($this->versiondb < $this->versiondisk) { 00875 return plugin_manager::PLUGIN_STATUS_UPGRADE; 00876 00877 } else if ($this->versiondb > $this->versiondisk) { 00878 return plugin_manager::PLUGIN_STATUS_DOWNGRADE; 00879 00880 } else { 00881 // $version = pi(); and similar funny jokes - hopefully Donald E. Knuth will never contribute to Moodle ;-) 00882 throw new coding_exception('Unable to determine plugin state, check the plugin versions'); 00883 } 00884 } 00885 00889 public function is_enabled() { 00890 return null; 00891 } 00892 00896 public function get_settings_url() { 00897 return null; 00898 } 00899 00903 public function get_uninstall_url() { 00904 return null; 00905 } 00906 00910 public function get_dir() { 00911 global $CFG; 00912 00913 return substr($this->rootdir, strlen($CFG->dirroot)); 00914 } 00915 00923 protected function get_version_from_config_plugins($plugin, $disablecache=false) { 00924 global $DB; 00925 static $pluginversions = null; 00926 00927 if (is_null($pluginversions) or $disablecache) { 00928 try { 00929 $pluginversions = $DB->get_records_menu('config_plugins', array('name' => 'version'), 'plugin', 'plugin,value'); 00930 } catch (dml_exception $e) { 00931 // before install 00932 $pluginversions = array(); 00933 } 00934 } 00935 00936 if (!array_key_exists($plugin, $pluginversions)) { 00937 return false; 00938 } 00939 00940 return $pluginversions[$plugin]; 00941 } 00942 } 00943 00947 class plugintype_general extends plugintype_base implements plugin_information { 00948 00949 } 00950 00954 class plugintype_block extends plugintype_base implements plugin_information { 00955 00959 public static function get_plugins($type, $typerootdir, $typeclass) { 00960 00961 // get the information about blocks at the disk 00962 $blocks = parent::get_plugins($type, $typerootdir, $typeclass); 00963 00964 // add blocks missing from disk 00965 $blocksinfo = self::get_blocks_info(); 00966 foreach ($blocksinfo as $blockname => $blockinfo) { 00967 if (isset($blocks[$blockname])) { 00968 continue; 00969 } 00970 $plugin = new $typeclass(); 00971 $plugin->type = $type; 00972 $plugin->typerootdir = $typerootdir; 00973 $plugin->name = $blockname; 00974 $plugin->rootdir = null; 00975 $plugin->displayname = $blockname; 00976 $plugin->versiondb = $blockinfo->version; 00977 $plugin->init_is_standard(); 00978 00979 $blocks[$blockname] = $plugin; 00980 } 00981 00982 return $blocks; 00983 } 00984 00988 public function init_display_name() { 00989 00990 if (get_string_manager()->string_exists('pluginname', 'block_' . $this->name)) { 00991 $this->displayname = get_string('pluginname', 'block_' . $this->name); 00992 00993 } else if (($block = block_instance($this->name)) !== false) { 00994 $this->displayname = $block->get_title(); 00995 00996 } else { 00997 parent::init_display_name(); 00998 } 00999 } 01000 01004 public function load_db_version() { 01005 global $DB; 01006 01007 $blocksinfo = self::get_blocks_info(); 01008 if (isset($blocksinfo[$this->name]->version)) { 01009 $this->versiondb = $blocksinfo[$this->name]->version; 01010 } 01011 } 01012 01016 public function is_enabled() { 01017 01018 $blocksinfo = self::get_blocks_info(); 01019 if (isset($blocksinfo[$this->name]->visible)) { 01020 if ($blocksinfo[$this->name]->visible) { 01021 return true; 01022 } else { 01023 return false; 01024 } 01025 } else { 01026 return parent::is_enabled(); 01027 } 01028 } 01029 01033 public function get_settings_url() { 01034 01035 if (($block = block_instance($this->name)) === false) { 01036 return parent::get_settings_url(); 01037 01038 } else if ($block->has_config()) { 01039 if (file_exists($this->full_path('settings.php'))) { 01040 return new moodle_url('/admin/settings.php', array('section' => 'blocksetting' . $this->name)); 01041 } else { 01042 $blocksinfo = self::get_blocks_info(); 01043 return new moodle_url('/admin/block.php', array('block' => $blocksinfo[$this->name]->id)); 01044 } 01045 01046 } else { 01047 return parent::get_settings_url(); 01048 } 01049 } 01050 01054 public function get_uninstall_url() { 01055 01056 $blocksinfo = self::get_blocks_info(); 01057 return new moodle_url('/admin/blocks.php', array('delete' => $blocksinfo[$this->name]->id, 'sesskey' => sesskey())); 01058 } 01059 01066 protected static function get_blocks_info($disablecache=false) { 01067 global $DB; 01068 static $blocksinfocache = null; 01069 01070 if (is_null($blocksinfocache) or $disablecache) { 01071 try { 01072 $blocksinfocache = $DB->get_records('block', null, 'name', 'name,id,version,visible'); 01073 } catch (dml_exception $e) { 01074 // before install 01075 $blocksinfocache = array(); 01076 } 01077 } 01078 01079 return $blocksinfocache; 01080 } 01081 } 01082 01086 class plugintype_filter extends plugintype_base implements plugin_information { 01087 01091 public static function get_plugins($type, $typerootdir, $typeclass) { 01092 global $CFG, $DB; 01093 01094 $filters = array(); 01095 01096 // get the list of filters from both /filter and /mod location 01097 $installed = filter_get_all_installed(); 01098 01099 foreach ($installed as $filterlegacyname => $displayname) { 01100 $plugin = new $typeclass(); 01101 $plugin->type = $type; 01102 $plugin->typerootdir = $typerootdir; 01103 $plugin->name = self::normalize_legacy_name($filterlegacyname); 01104 $plugin->rootdir = $CFG->dirroot . '/' . $filterlegacyname; 01105 $plugin->displayname = $displayname; 01106 01107 $plugin->load_disk_version(); 01108 $plugin->load_db_version(); 01109 $plugin->load_required_main_version(); 01110 $plugin->init_is_standard(); 01111 01112 $filters[$plugin->name] = $plugin; 01113 } 01114 01115 $globalstates = self::get_global_states(); 01116 01117 if ($DB->get_manager()->table_exists('filter_active')) { 01118 // if we're upgrading from 1.9, the table does not exist yet 01119 // if it does, make sure that all installed filters are registered 01120 $needsreload = false; 01121 foreach (array_keys($installed) as $filterlegacyname) { 01122 if (!isset($globalstates[self::normalize_legacy_name($filterlegacyname)])) { 01123 filter_set_global_state($filterlegacyname, TEXTFILTER_DISABLED); 01124 $needsreload = true; 01125 } 01126 } 01127 if ($needsreload) { 01128 $globalstates = self::get_global_states(true); 01129 } 01130 } 01131 01132 // make sure that all registered filters are installed, just in case 01133 foreach ($globalstates as $name => $info) { 01134 if (!isset($filters[$name])) { 01135 // oops, there is a record in filter_active but the filter is not installed 01136 $plugin = new $typeclass(); 01137 $plugin->type = $type; 01138 $plugin->typerootdir = $typerootdir; 01139 $plugin->name = $name; 01140 $plugin->rootdir = $CFG->dirroot . '/' . $info->legacyname; 01141 $plugin->displayname = $info->legacyname; 01142 01143 $plugin->load_db_version(); 01144 01145 if (is_null($plugin->versiondb)) { 01146 // this is a hack to stimulate 'Missing from disk' error 01147 // because $plugin->versiondisk will be null !== false 01148 $plugin->versiondb = false; 01149 } 01150 01151 $filters[$plugin->name] = $plugin; 01152 } 01153 } 01154 01155 return $filters; 01156 } 01157 01161 public function init_display_name() { 01162 // do nothing, the name is set in self::get_plugins() 01163 } 01164 01168 protected function load_version_php() { 01169 if (strpos($this->name, 'mod_') === 0) { 01170 // filters bundled with modules do not have a version.php and so 01171 // do not provide their own versioning information. 01172 return new stdClass(); 01173 } 01174 return parent::load_version_php(); 01175 } 01176 01180 public function is_enabled() { 01181 01182 $globalstates = self::get_global_states(); 01183 01184 foreach ($globalstates as $filterlegacyname => $info) { 01185 $name = self::normalize_legacy_name($filterlegacyname); 01186 if ($name === $this->name) { 01187 if ($info->active == TEXTFILTER_DISABLED) { 01188 return false; 01189 } else { 01190 // it may be 'On' or 'Off, but available' 01191 return null; 01192 } 01193 } 01194 } 01195 01196 return null; 01197 } 01198 01202 public function get_settings_url() { 01203 01204 $globalstates = self::get_global_states(); 01205 $legacyname = $globalstates[$this->name]->legacyname; 01206 if (filter_has_global_settings($legacyname)) { 01207 return new moodle_url('/admin/settings.php', array('section' => 'filtersetting' . str_replace('/', '', $legacyname))); 01208 } else { 01209 return null; 01210 } 01211 } 01212 01216 public function get_uninstall_url() { 01217 01218 if (strpos($this->name, 'mod_') === 0) { 01219 return null; 01220 } else { 01221 $globalstates = self::get_global_states(); 01222 $legacyname = $globalstates[$this->name]->legacyname; 01223 return new moodle_url('/admin/filters.php', array('sesskey' => sesskey(), 'filterpath' => $legacyname, 'action' => 'delete')); 01224 } 01225 } 01226 01233 protected static function normalize_legacy_name($legacyfiltername) { 01234 01235 $name = str_replace('/', '_', $legacyfiltername); 01236 if (strpos($name, 'filter_') === 0) { 01237 $name = substr($name, 7); 01238 if (empty($name)) { 01239 throw new coding_exception('Unable to determine filter name: ' . $legacyfiltername); 01240 } 01241 } 01242 01243 return $name; 01244 } 01245 01255 protected static function get_global_states($disablecache=false) { 01256 global $DB; 01257 static $globalstatescache = null; 01258 01259 if ($disablecache or is_null($globalstatescache)) { 01260 01261 if (!$DB->get_manager()->table_exists('filter_active')) { 01262 // we're upgrading from 1.9 and the table used by {@link filter_get_global_states()} 01263 // does not exist yet 01264 $globalstatescache = array(); 01265 01266 } else { 01267 foreach (filter_get_global_states() as $legacyname => $info) { 01268 $name = self::normalize_legacy_name($legacyname); 01269 $filterinfo = new stdClass(); 01270 $filterinfo->legacyname = $legacyname; 01271 $filterinfo->active = $info->active; 01272 $filterinfo->sortorder = $info->sortorder; 01273 $globalstatescache[$name] = $filterinfo; 01274 } 01275 } 01276 } 01277 01278 return $globalstatescache; 01279 } 01280 } 01281 01285 class plugintype_mod extends plugintype_base implements plugin_information { 01286 01290 public static function get_plugins($type, $typerootdir, $typeclass) { 01291 01292 // get the information about plugins at the disk 01293 $modules = parent::get_plugins($type, $typerootdir, $typeclass); 01294 01295 // add modules missing from disk 01296 $modulesinfo = self::get_modules_info(); 01297 foreach ($modulesinfo as $modulename => $moduleinfo) { 01298 if (isset($modules[$modulename])) { 01299 continue; 01300 } 01301 $plugin = new $typeclass(); 01302 $plugin->type = $type; 01303 $plugin->typerootdir = $typerootdir; 01304 $plugin->name = $modulename; 01305 $plugin->rootdir = null; 01306 $plugin->displayname = $modulename; 01307 $plugin->versiondb = $moduleinfo->version; 01308 $plugin->init_is_standard(); 01309 01310 $modules[$modulename] = $plugin; 01311 } 01312 01313 return $modules; 01314 } 01315 01319 public function init_display_name() { 01320 if (get_string_manager()->string_exists('pluginname', $this->component)) { 01321 $this->displayname = get_string('pluginname', $this->component); 01322 } else { 01323 $this->displayname = get_string('modulename', $this->component); 01324 } 01325 } 01326 01331 protected function load_version_php() { 01332 $versionfile = $this->full_path('version.php'); 01333 01334 $module = new stdClass(); 01335 if (is_readable($versionfile)) { 01336 include($versionfile); 01337 } 01338 return $module; 01339 } 01340 01344 public function load_db_version() { 01345 global $DB; 01346 01347 $modulesinfo = self::get_modules_info(); 01348 if (isset($modulesinfo[$this->name]->version)) { 01349 $this->versiondb = $modulesinfo[$this->name]->version; 01350 } 01351 } 01352 01356 public function is_enabled() { 01357 01358 $modulesinfo = self::get_modules_info(); 01359 if (isset($modulesinfo[$this->name]->visible)) { 01360 if ($modulesinfo[$this->name]->visible) { 01361 return true; 01362 } else { 01363 return false; 01364 } 01365 } else { 01366 return parent::is_enabled(); 01367 } 01368 } 01369 01373 public function get_settings_url() { 01374 01375 if (file_exists($this->full_path('settings.php')) or file_exists($this->full_path('settingstree.php'))) { 01376 return new moodle_url('/admin/settings.php', array('section' => 'modsetting' . $this->name)); 01377 } else { 01378 return parent::get_settings_url(); 01379 } 01380 } 01381 01385 public function get_uninstall_url() { 01386 01387 if ($this->name !== 'forum') { 01388 return new moodle_url('/admin/modules.php', array('delete' => $this->name, 'sesskey' => sesskey())); 01389 } else { 01390 return null; 01391 } 01392 } 01393 01400 protected static function get_modules_info($disablecache=false) { 01401 global $DB; 01402 static $modulesinfocache = null; 01403 01404 if (is_null($modulesinfocache) or $disablecache) { 01405 try { 01406 $modulesinfocache = $DB->get_records('modules', null, 'name', 'name,id,version,visible'); 01407 } catch (dml_exception $e) { 01408 // before install 01409 $modulesinfocache = array(); 01410 } 01411 } 01412 01413 return $modulesinfocache; 01414 } 01415 } 01416 01417 01421 class plugintype_qbehaviour extends plugintype_base implements plugin_information { 01425 public function get_uninstall_url() { 01426 return new moodle_url('/admin/qbehaviours.php', 01427 array('delete' => $this->name, 'sesskey' => sesskey())); 01428 } 01429 } 01430 01431 01435 class plugintype_qtype extends plugintype_base implements plugin_information { 01439 public function get_uninstall_url() { 01440 return new moodle_url('/admin/qtypes.php', 01441 array('delete' => $this->name, 'sesskey' => sesskey())); 01442 } 01443 } 01444 01445 01449 class plugintype_auth extends plugintype_base implements plugin_information { 01450 01454 public function is_enabled() { 01455 global $CFG; 01457 static $enabled = null; 01458 01459 if (in_array($this->name, array('nologin', 'manual'))) { 01460 // these two are always enabled and can't be disabled 01461 return null; 01462 } 01463 01464 if (is_null($enabled)) { 01465 $enabled = array_flip(explode(',', $CFG->auth)); 01466 } 01467 01468 return isset($enabled[$this->name]); 01469 } 01470 01474 public function get_settings_url() { 01475 if (file_exists($this->full_path('settings.php'))) { 01476 return new moodle_url('/admin/settings.php', array('section' => 'authsetting' . $this->name)); 01477 } else { 01478 return new moodle_url('/admin/auth_config.php', array('auth' => $this->name)); 01479 } 01480 } 01481 } 01482 01486 class plugintype_enrol extends plugintype_base implements plugin_information { 01487 01496 public function is_enabled() { 01497 global $CFG; 01499 static $enabled = null; 01500 01501 if (is_null($enabled)) { 01502 $enabled = array_flip(explode(',', $CFG->enrol_plugins_enabled)); 01503 } 01504 01505 return isset($enabled[$this->name]); 01506 } 01507 01511 public function get_settings_url() { 01512 01513 if ($this->is_enabled() or file_exists($this->full_path('settings.php'))) { 01514 return new moodle_url('/admin/settings.php', array('section' => 'enrolsettings' . $this->name)); 01515 } else { 01516 return parent::get_settings_url(); 01517 } 01518 } 01519 01523 public function get_uninstall_url() { 01524 return new moodle_url('/admin/enrol.php', array('action' => 'uninstall', 'enrol' => $this->name, 'sesskey' => sesskey())); 01525 } 01526 } 01527 01531 class plugintype_message extends plugintype_base implements plugin_information { 01532 01536 public function get_settings_url() { 01537 01538 if (file_exists($this->full_path('settings.php')) or file_exists($this->full_path('settingstree.php'))) { 01539 return new moodle_url('/admin/settings.php', array('section' => 'messagesetting' . $this->name)); 01540 } else { 01541 return parent::get_settings_url(); 01542 } 01543 } 01544 } 01545 01549 class plugintype_repository extends plugintype_base implements plugin_information { 01550 01554 public function is_enabled() { 01555 01556 $enabled = self::get_enabled_repositories(); 01557 01558 return isset($enabled[$this->name]); 01559 } 01560 01564 public function get_settings_url() { 01565 01566 if ($this->is_enabled()) { 01567 return new moodle_url('/admin/repository.php', array('sesskey' => sesskey(), 'action' => 'edit', 'repos' => $this->name)); 01568 } else { 01569 return parent::get_settings_url(); 01570 } 01571 } 01572 01579 protected static function get_enabled_repositories($disablecache=false) { 01580 global $DB; 01581 static $repositories = null; 01582 01583 if (is_null($repositories) or $disablecache) { 01584 $repositories = $DB->get_records('repository', null, 'type', 'type,visible,sortorder'); 01585 } 01586 01587 return $repositories; 01588 } 01589 } 01590 01594 class plugintype_portfolio extends plugintype_base implements plugin_information { 01595 01599 public function is_enabled() { 01600 01601 $enabled = self::get_enabled_portfolios(); 01602 01603 return isset($enabled[$this->name]); 01604 } 01605 01612 protected static function get_enabled_portfolios($disablecache=false) { 01613 global $DB; 01614 static $portfolios = null; 01615 01616 if (is_null($portfolios) or $disablecache) { 01617 $portfolios = array(); 01618 $instances = $DB->get_recordset('portfolio_instance', null, 'plugin'); 01619 foreach ($instances as $instance) { 01620 if (isset($portfolios[$instance->plugin])) { 01621 if ($instance->visible) { 01622 $portfolios[$instance->plugin]->visible = $instance->visible; 01623 } 01624 } else { 01625 $portfolios[$instance->plugin] = $instance; 01626 } 01627 } 01628 } 01629 01630 return $portfolios; 01631 } 01632 } 01633 01637 class plugintype_theme extends plugintype_base implements plugin_information { 01638 01642 public function is_enabled() { 01643 global $CFG; 01644 01645 if ((!empty($CFG->theme) and $CFG->theme === $this->name) or 01646 (!empty($CFG->themelegacy) and $CFG->themelegacy === $this->name)) { 01647 return true; 01648 } else { 01649 return parent::is_enabled(); 01650 } 01651 } 01652 } 01653 01657 class plugintype_mnetservice extends plugintype_base implements plugin_information { 01658 01662 public function is_enabled() { 01663 global $CFG; 01664 01665 if (empty($CFG->mnet_dispatcher_mode) || $CFG->mnet_dispatcher_mode !== 'strict') { 01666 return false; 01667 } else { 01668 return parent::is_enabled(); 01669 } 01670 } 01671 } 01672 01676 class plugintype_tool extends plugintype_base implements plugin_information { 01677 01678 public function get_uninstall_url() { 01679 return new moodle_url('/admin/tools.php', array('delete' => $this->name, 'sesskey' => sesskey())); 01680 } 01681 } 01682 01686 class plugintype_report extends plugintype_base implements plugin_information { 01687 01688 public function get_uninstall_url() { 01689 return new moodle_url('/admin/reports.php', array('delete' => $this->name, 'sesskey' => sesskey())); 01690 } 01691 }