/** * Returns a list of all components installed on the server * * @return array (string)legacyname => (string)frankenstylename */ public static function list_components() { $list['moodle'] = 'core'; $coresubsystems = get_core_subsystems(); ksort($coresubsystems); // should be but just in case foreach ($coresubsystems as $name => $location) { if ($name != 'moodle.org') { $list[$name] = 'core_' . $name; } } $plugintypes = get_plugin_types(); foreach ($plugintypes as $type => $location) { $pluginlist = get_plugin_list($type); foreach ($pluginlist as $name => $ununsed) { if ($type == 'mod') { if (array_key_exists($name, $list)) { throw new Exception('Activity module and core subsystem name collision'); } $list[$name] = $type . '_' . $name; } else { $list[$type . '_' . $name] = $type . '_' . $name; } } } return $list; }
/** * Return exact path to plugin directory * @param string $plugintype type of plugin * @param string $name name of the plugin * @param bool $fullpaths false means relative paths from dirroot * @return directory path, full or relative to dirroot */ function get_plugin_directory($plugintype, $name, $fullpaths = true) { if ($plugintype === '') { $plugintype = 'mod'; } $types = get_plugin_types($fullpaths); if (!array_key_exists($plugintype, $types)) { return null; } $name = clean_param($name, PARAM_SAFEDIR); // just in case ;-) return $types[$plugintype] . '/' . $name; }
/** * Constructor. * @throws Command_Exception. */ function __construct() { global $DB; // Getting command description. $cmd_name = vmoodle_get_string('cmdsyncname', 'vmoodleadminset_plugins'); $cmd_desc = vmoodle_get_string('cmdsyncdesc', 'vmoodleadminset_plugins'); // Creating platform parameter. This is the source platform. $platform_param = new Command_Parameter('platform', 'enum', vmoodle_get_string('platformparamsyncdesc', 'vmoodleadminset_plugins'), null, get_available_platforms()); // Creating plugins type parameter. If this parameter has a value, // then all plugins in this type will be synchronized $plugintypes = get_plugin_types(); $plugintype_param = new Command_Parameter('plugintype', 'enum', vmoodle_get_string('plugintypeparamsyncdesc', 'vmoodleadminset_plugins'), null, $plugintypes); // Creating command. parent::__construct($cmd_name, $cmd_desc, array($platform_param, $plugintype_param)); }
/** * Returns all the plugins having tests * @param string $testtype The kind of test we are looking for * @return array all the plugins having tests */ private static function get_all_plugins_with_tests($testtype) { $pluginswithtests = array(); $plugintypes = get_plugin_types(); ksort($plugintypes); foreach ($plugintypes as $type => $unused) { $plugs = get_plugin_list($type); ksort($plugs); foreach ($plugs as $plug => $fullplug) { // Look for tests recursively if (self::directory_has_tests($fullplug, $testtype)) { $pluginswithtests[$type . '_' . $plug] = $fullplug; } } } return $pluginswithtests; }
/** * Returns an array of organised CSS files required for this output * * @return array */ public function css_files() { $cssfiles = array('plugins' => array(), 'parents' => array(), 'theme' => array()); // get all plugin sheets $excludes = $this->resolve_excludes('plugins_exclude_sheets'); if ($excludes !== true) { foreach (get_plugin_types() as $type => $unused) { if ($type === 'theme' || (!empty($excludes[$type]) and $excludes[$type] === true)) { continue; } $plugins = get_plugin_list($type); foreach ($plugins as $plugin => $fulldir) { if (!empty($excludes[$type]) and is_array($excludes[$type]) and in_array($plugin, $excludes[$type])) { continue; } $plugincontent = ''; $sheetfile = "{$fulldir}/styles.css"; if (is_readable($sheetfile)) { $cssfiles['plugins'][$type . '_' . $plugin] = $sheetfile; } $sheetthemefile = "{$fulldir}/styles_{$this->name}.css"; if (is_readable($sheetthemefile)) { $cssfiles['plugins'][$type . '_' . $plugin . '_' . $this->name] = $sheetthemefile; } } } } // find out wanted parent sheets $excludes = $this->resolve_excludes('parents_exclude_sheets'); if ($excludes !== true) { foreach (array_reverse($this->parent_configs) as $parent_config) { // base first, the immediate parent last $parent = $parent_config->name; if (empty($parent_config->sheets) || (!empty($excludes[$parent]) and $excludes[$parent] === true)) { continue; } foreach ($parent_config->sheets as $sheet) { if (!empty($excludes[$parent]) and is_array($excludes[$parent]) and in_array($sheet, $excludes[$parent])) { continue; } $sheetfile = "{$parent_config->dir}/style/{$sheet}.css"; if (is_readable($sheetfile)) { $cssfiles['parents'][$parent][$sheet] = $sheetfile; } } } } // current theme sheets if (is_array($this->sheets)) { foreach ($this->sheets as $sheet) { $sheetfile = "{$this->dir}/style/{$sheet}.css"; if (is_readable($sheetfile)) { $cssfiles['theme'][$sheet] = $sheetfile; } } } return $cssfiles; }
/** * Very hacky function for rebuilding of log actions in target database. * @param moodle_database $target * @param progress_trace $feedback * @return void * @throws Exception on conversion error */ function tool_dbtransfer_rebuild_target_log_actions(moodle_database $target, progress_trace $feedback = null) { global $DB, $CFG; require_once "{$CFG->libdir}/upgradelib.php"; $feedback->output(get_string('convertinglogdisplay', 'tool_dbtransfer')); $olddb = $DB; $DB = $target; try { $DB->delete_records('log_display', array('component' => 'moodle')); log_update_descriptions('moodle'); $plugintypes = get_plugin_types(); foreach ($plugintypes as $type => $location) { $plugs = get_plugin_list($type); foreach ($plugs as $plug => $fullplug) { $component = $type . '_' . $plug; $DB->delete_records('log_display', array('component' => $component)); log_update_descriptions($component); } } } catch (Exception $e) { $DB = $olddb; throw $e; } $DB = $olddb; $feedback->output(get_string('done', 'core_dbtransfer', null), 1); }
/** * Determine if moodle installation requires update * * Checks version numbers of main code and all modules to see * if there are any mismatches * * @global object * @global object * @return bool */ function moodle_needs_upgrading() { global $CFG, $DB, $OUTPUT; if (empty($CFG->version)) { return true; } // main versio nfirst $version = null; include $CFG->dirroot . '/version.php'; // defines $version and upgrades if ($version > $CFG->version) { return true; } // modules $mods = get_plugin_list('mod'); $installed = $DB->get_records('modules', array(), '', 'name, version'); foreach ($mods as $mod => $fullmod) { if ($mod === 'NEWMODULE') { // Someone has unzipped the template, ignore it continue; } $module = new stdClass(); if (!is_readable($fullmod . '/version.php')) { continue; } include $fullmod . '/version.php'; // defines $module with version etc if (empty($installed[$mod])) { return true; } else { if ($module->version > $installed[$mod]->version) { return true; } } } unset($installed); // blocks $blocks = get_plugin_list('block'); $installed = $DB->get_records('block', array(), '', 'name, version'); require_once $CFG->dirroot . '/blocks/moodleblock.class.php'; foreach ($blocks as $blockname => $fullblock) { if ($blockname === 'NEWBLOCK') { // Someone has unzipped the template, ignore it continue; } if (!is_readable($fullblock . '/version.php')) { continue; } $plugin = new stdClass(); $plugin->version = NULL; include $fullblock . '/version.php'; if (empty($installed[$blockname])) { return true; } else { if ($plugin->version > $installed[$blockname]->version) { return true; } } } unset($installed); // now the rest of plugins $plugintypes = get_plugin_types(); unset($plugintypes['mod']); unset($plugintypes['block']); foreach ($plugintypes as $type => $unused) { $plugs = get_plugin_list($type); foreach ($plugs as $plug => $fullplug) { $component = $type . '_' . $plug; if (!is_readable($fullplug . '/version.php')) { continue; } $plugin = new stdClass(); include $fullplug . '/version.php'; // defines $plugin with version etc $installedversion = get_config($component, 'version'); if (empty($installedversion)) { // new installation return true; } else { if ($installedversion < $plugin->version) { // upgrade return true; } } } } return false; }
/** * Function to require any potential callback files, throwing exceptions * if an issue occurs. * * @param string $callbackfile This is the location of the callback file '/mod/forum/locallib.php' * @param string $class Name of the class containing the callback functions * activity components should ALWAYS use their name_portfolio_caller * other locations must use something unique */ function portfolio_include_callback_file($callbackfile, $class = null) { global $CFG; require_once($CFG->libdir . '/adminlib.php'); // Get the last occurrence of '/' in the file path. $pos = strrpos($callbackfile, '/'); // Get rid of the first slash (if it exists). $callbackfile = ltrim($callbackfile, '/'); // Get a list of valid plugin types. $plugintypes = get_plugin_types(false); // Assume it is not valid for now. $isvalid = false; // Go through the plugin types. foreach ($plugintypes as $type => $path) { if (strrpos($callbackfile, $path) === 0) { // Found the plugin type. $isvalid = true; $plugintype = $type; $pluginpath = $path; } } // Throw exception if not a valid component. if (!$isvalid) { throw new coding_exception('Somehow a non-valid plugin path was passed, could be a hackz0r attempt, exiting.'); } // Keep record of the filename. $filename = substr($callbackfile, $pos); // Remove the file name. $component = trim(substr($callbackfile, 0, $pos), '/'); // Replace the path with the type. $component = str_replace($pluginpath, $plugintype, $component); // Ok, replace '/' with '_'. $component = str_replace('/', '_', $component); // Check that it is a valid component. if (!get_component_version($component)) { throw new portfolio_button_exception('nocallbackcomponent', 'portfolio', '', $component); } // Obtain the component's location. if (!$componentloc = get_component_directory($component)) { throw new portfolio_button_exception('nocallbackcomponent', 'portfolio', '', $component); } // Check if the filename does not meet any of the expected names. if (($filename != 'locallib.php') && ($filename != 'portfoliolib.php') && ($filename != 'portfolio_callback.php')) { debugging('Please standardise your plugin by keeping your portfolio callback functionality in the file locallib.php.', DEBUG_DEVELOPER); } // Throw error if file does not exist. if (!file_exists($componentloc . '/' . $filename)) { throw new portfolio_button_exception('nocallbackfile', 'portfolio', '', $callbackfile); } require_once($componentloc . '/' . $filename); if (!is_null($class) && !class_exists($class)) { throw new portfolio_button_exception('nocallbackclass', 'portfolio', '', $class); } }
/** * Get the relative path for a plugin given it's type * * @param string $type * The plugin type (example: 'auth', 'block') * @param string $moodleversion * The version of moodle we are running (example: '1.9', '2.9') * @return string * The installation path relative to dirroot (example: 'auth', 'blocks', * 'course/format') */ private function get_install_path($type) { global $CFG; if ($this->moodlerelease >= 2.6) { $types = \core_component::get_plugin_types(); } else { if ($this->moodlerelease >= 2.0) { $types = get_plugin_types(); } else { // Moodle 1.9 does not give us a way to determine plugin // installation paths. $types = array(); } } if (empty($types) || !array_key_exists($type, $types)) { // Either the moodle version is lower than 2.0, in which case we // don't have a reliable way of determining the install path, or the // plugin is of an unknown type. // // Let's fall back to make our best guess. return $CFG->dirroot . '/' . $type; } return $types[$type]; }
/** * Prepares a renderable widget to execute installation of an available update. * * @param available_update_info $info component version to deploy * @return renderable */ public function make_execution_widget(available_update_info $info) { global $CFG; if (!$this->initialized()) { throw new coding_exception('Illegal method call - deployer not initialized.'); } $pluginrootpaths = get_plugin_types(true); list($plugintype, $pluginname) = normalize_component($info->component); if (empty($pluginrootpaths[$plugintype])) { throw new coding_exception('Unknown plugin type root location', $plugintype); } list($passfile, $password) = $this->prepare_authorization(); $upgradeurl = new moodle_url('/admin'); $params = array( 'upgrade' => true, 'type' => $plugintype, 'name' => $pluginname, 'typeroot' => $pluginrootpaths[$plugintype], 'package' => $info->download, 'md5' => $info->downloadmd5, 'dataroot' => $CFG->dataroot, 'dirroot' => $CFG->dirroot, 'passfile' => $passfile, 'password' => $password, 'returnurl' => $upgradeurl->out(true), ); $widget = new single_button( new moodle_url('/mdeploy.php', $params), get_string('updateavailableinstall', 'core_admin'), 'post' ); return $widget; }
/** * Upgrade/install other parts of moodle * @param bool $verbose * @return void, may throw exception */ function upgrade_noncore($verbose) { global $CFG; raise_memory_limit(MEMORY_EXTRA); // upgrade all plugins types try { $plugintypes = get_plugin_types(); foreach ($plugintypes as $type=>$location) { upgrade_plugins($type, 'print_upgrade_part_start', 'print_upgrade_part_end', $verbose); } // Update cache definitions. Involves scanning each plugin for any changes. cache_helper::update_definitions(); } catch (Exception $ex) { upgrade_handle_exception($ex); } }
/** * Function to require any potential callback files, throwing exceptions * if an issue occurs. * * @param string $component This is the name of the component in Moodle, eg 'mod_forum' * @param string $class Name of the class containing the callback functions * activity components should ALWAYS use their name_portfolio_caller * other locations must use something unique */ function portfolio_include_callback_file($component, $class = null) { global $CFG; require_once $CFG->libdir . '/adminlib.php'; // It's possible that they are passing a file path rather than passing a component. // We want to try and convert this to a component name, eg. mod_forum. $pos = strrpos($component, '/'); if ($pos !== false) { // Get rid of the first slash (if it exists). $component = ltrim($component, '/'); // Get a list of valid plugin types. $plugintypes = get_plugin_types(false); // Assume it is not valid for now. $isvalid = false; // Go through the plugin types. foreach ($plugintypes as $type => $path) { if (strrpos($component, $path) === 0) { // Found the plugin type. $isvalid = true; $plugintype = $type; $pluginpath = $path; } } // Throw exception if not a valid component. if (!$isvalid) { throw new coding_exception('Somehow a non-valid plugin path was passed, could be a hackz0r attempt, exiting.'); } // Remove the file name. $component = trim(substr($component, 0, $pos), '/'); // Replace the path with the type. $component = str_replace($pluginpath, $plugintype, $component); // Ok, replace '/' with '_'. $component = str_replace('/', '_', $component); // Place a debug message saying the third parameter should be changed. debugging('The third parameter sent to the function set_callback_options should be the component name, not a file path, please update this.', DEBUG_DEVELOPER); } // Check that it is a valid component. if (!get_component_version($component)) { throw new portfolio_button_exception('nocallbackcomponent', 'portfolio', '', $component); } // Obtain the component's location. if (!($componentloc = get_component_directory($component))) { throw new portfolio_button_exception('nocallbackcomponent', 'portfolio', '', $component); } // Check if the component contains the necessary file for the portfolio plugin. // These are locallib.php, portfoliolib.php and portfolio_callback.php. $filefound = false; if (file_exists($componentloc . '/locallib.php')) { $filefound = true; require_once $componentloc . '/locallib.php'; } if (file_exists($componentloc . '/portfoliolib.php')) { $filefound = true; debugging('Please standardise your plugin by renaming your portfolio callback file to locallib.php, or if that file already exists moving the portfolio functionality there.', DEBUG_DEVELOPER); require_once $componentloc . '/portfoliolib.php'; } if (file_exists($componentloc . '/portfolio_callback.php')) { $filefound = true; debugging('Please standardise your plugin by renaming your portfolio callback file to locallib.php, or if that file already exists moving the portfolio functionality there.', DEBUG_DEVELOPER); require_once $componentloc . '/portfolio_callback.php'; } // Ensure that we found a file we can use, if not throw an exception. if (!$filefound) { throw new portfolio_button_exception('nocallbackfile', 'portfolio', '', $component); } if (!is_null($class) && !class_exists($class)) { throw new portfolio_button_exception('nocallbackclass', 'portfolio', '', $class); } }
/** * Calculate unique version hash for all plugins and core. * @static * @return string sha1 hash */ public static function get_version_hash() { global $CFG; if (self::$versionhash) { return self::$versionhash; } $versions = array(); // main version first $version = null; include($CFG->dirroot.'/version.php'); $versions['core'] = $version; // modules $mods = get_plugin_list('mod'); ksort($mods); foreach ($mods as $mod => $fullmod) { $module = new stdClass(); $module->version = null; include($fullmod.'/version.php'); $versions[$mod] = $module->version; } // now the rest of plugins $plugintypes = get_plugin_types(); unset($plugintypes['mod']); ksort($plugintypes); foreach ($plugintypes as $type => $unused) { $plugs = get_plugin_list($type); ksort($plugs); foreach ($plugs as $plug => $fullplug) { $plugin = new stdClass(); $plugin->version = null; @include($fullplug.'/version.php'); $versions[$plug] = $plugin->version; } } self::$versionhash = sha1(serialize($versions)); return self::$versionhash; }
/** * Returns a tree of known plugins and information about them * * @param bool $disablecache force reload, cache can be used otherwise * @return array 2D array. The first keys are plugin type names (e.g. qtype); * the second keys are the plugin local name (e.g. multichoice); and * the values are the corresponding objects extending {@link plugininfo_base} */ public function get_plugins($disablecache = false) { if ($disablecache or is_null($this->pluginsinfo)) { $this->pluginsinfo = array(); $plugintypes = get_plugin_types(); $plugintypes = $this->reorder_plugin_types($plugintypes); foreach ($plugintypes as $plugintype => $plugintyperootdir) { if (in_array($plugintype, array('base', 'general'))) { throw new coding_exception('Illegal usage of reserved word for plugin type'); } if (class_exists('plugininfo_' . $plugintype)) { $plugintypeclass = 'plugininfo_' . $plugintype; } else { $plugintypeclass = 'plugininfo_general'; } if (!in_array('plugininfo_base', class_parents($plugintypeclass))) { throw new coding_exception('Class ' . $plugintypeclass . ' must extend plugininfo_base'); } $plugins = call_user_func(array($plugintypeclass, 'get_plugins'), $plugintype, $plugintyperootdir, $plugintypeclass); $this->pluginsinfo[$plugintype] = $plugins; } // TODO: MDL-20438 verify this is the correct solution/replace if (!during_initial_install()) { // append the information about available updates provided by {@link available_update_checker()} $provider = available_update_checker::instance(); foreach ($this->pluginsinfo as $plugintype => $plugins) { foreach ($plugins as $plugininfoholder) { $plugininfoholder->check_available_updates($provider); } } } } return $this->pluginsinfo; }
/** * Upgrade/install other parts of moodle * @param bool $verbose * @return void, may throw exception */ function upgrade_noncore($verbose) { global $CFG; // upgrade all plugins types try { $plugintypes = get_plugin_types(); foreach ($plugintypes as $type => $location) { upgrade_plugins($type, 'print_upgrade_part_start', 'print_upgrade_part_end', $verbose); } } catch (Exception $ex) { upgrade_handle_exception($ex); } // Check for changes to RPC functions if ($CFG->mnet_dispatcher_mode != 'off') { try { // this needs a full rewrite, sorry to mention that :-( // we have to make it part of standard WS framework require_once "{$CFG->dirroot}/{$CFG->admin}/mnet/adminlib.php"; upgrade_RPC_functions(); // Return here afterwards } catch (Exception $ex) { upgrade_handle_exception($ex); } } }
/** * Locates all of the definition files. * * @param bool $coreonly If set to true only core definitions will be updated. * @return array */ protected static function locate_definitions($coreonly = false) { global $CFG; $files = array(); if (file_exists($CFG->dirroot . '/lib/db/caches.php')) { $files['core'] = $CFG->dirroot . '/lib/db/caches.php'; } if (!$coreonly) { $plugintypes = get_plugin_types(); foreach ($plugintypes as $type => $location) { $plugins = get_plugin_list_with_file($type, 'db/caches.php'); foreach ($plugins as $plugin => $filepath) { $component = clean_param($type . '_' . $plugin, PARAM_COMPONENT); // Standardised plugin name. $files[$component] = $filepath; } } } $definitions = array(); foreach ($files as $component => $file) { $filedefs = self::load_caches_file($file); foreach ($filedefs as $area => $definition) { $area = clean_param($area, PARAM_AREA); $id = $component . '/' . $area; $definition['component'] = $component; $definition['area'] = $area; if (array_key_exists($id, $definitions)) { debugging('Error: duplicate cache definition found with id: ' . $id, DEBUG_DEVELOPER); continue; } $definitions[$id] = $definition; } } return $definitions; }
} } } } else { if ($version < $CFG->version) { notify("WARNING!!! The code you are using is OLDER than the version that made these databases!"); } } /// Updated human-readable release version if necessary if ($release != $CFG->release) { // Update the release version set_config("release", $release); } /// upgrade all plugins types try { $plugintypes = get_plugin_types(); foreach ($plugintypes as $type => $location) { upgrade_plugins($type, $location, 'print_upgrade_part_start', 'print_upgrade_part_end'); } } catch (Exception $ex) { upgrade_handle_exception($ex); } /// Check for changes to RPC functions if ($CFG->mnet_dispatcher_mode != 'off') { try { // this needs a full rewrite, sorry to mention that :-( require_once "{$CFG->dirroot}/{$CFG->admin}/mnet/adminlib.php"; upgrade_RPC_functions(); // Return here afterwards } catch (Exception $ex) { upgrade_handle_exception($ex);
/** * Determine if moodle installation requires update * * Checks version numbers of main code and all modules to see * if there are any mismatches * * @global moodle_database $DB * @return bool */ function moodle_needs_upgrading() { global $CFG, $DB, $OUTPUT; if (empty($CFG->version)) { return true; } // We have to purge plugin related caches now to be sure we have fresh data // and new plugins can be detected. cache::make('core', 'plugintypes')->purge(); cache::make('core', 'pluginlist')->purge(); cache::make('core', 'plugininfo_base')->purge(); cache::make('core', 'plugininfo_mod')->purge(); cache::make('core', 'plugininfo_block')->purge(); cache::make('core', 'plugininfo_filter')->purge(); cache::make('core', 'plugininfo_repository')->purge(); cache::make('core', 'plugininfo_portfolio')->purge(); // Check the main version first. $version = null; include $CFG->dirroot . '/version.php'; // defines $version and upgrades if ($version > $CFG->version) { return true; } // modules $mods = get_plugin_list('mod'); $installed = $DB->get_records('modules', array(), '', 'name, version'); foreach ($mods as $mod => $fullmod) { if ($mod === 'NEWMODULE') { // Someone has unzipped the template, ignore it continue; } $module = new stdClass(); $plugin = new stdClass(); if (!is_readable($fullmod . '/version.php')) { continue; } include $fullmod . '/version.php'; // defines $module with version etc if (!isset($module->version) and isset($plugin->version)) { $module = $plugin; } if (empty($installed[$mod])) { return true; } else { if ($module->version > $installed[$mod]->version) { return true; } } } unset($installed); // blocks $blocks = get_plugin_list('block'); $installed = $DB->get_records('block', array(), '', 'name, version'); require_once $CFG->dirroot . '/blocks/moodleblock.class.php'; foreach ($blocks as $blockname => $fullblock) { if ($blockname === 'NEWBLOCK') { // Someone has unzipped the template, ignore it continue; } if (!is_readable($fullblock . '/version.php')) { continue; } $plugin = new stdClass(); $plugin->version = NULL; include $fullblock . '/version.php'; if (empty($installed[$blockname])) { return true; } else { if ($plugin->version > $installed[$blockname]->version) { return true; } } } unset($installed); // now the rest of plugins $plugintypes = get_plugin_types(); unset($plugintypes['mod']); unset($plugintypes['block']); $versions = $DB->get_records_menu('config_plugins', array('name' => 'version'), 'plugin', 'plugin, value'); foreach ($plugintypes as $type => $unused) { $plugs = get_plugin_list($type); foreach ($plugs as $plug => $fullplug) { $component = $type . '_' . $plug; if (!is_readable($fullplug . '/version.php')) { continue; } $plugin = new stdClass(); include $fullplug . '/version.php'; // defines $plugin with version etc if (array_key_exists($component, $versions)) { $installedversion = $versions[$component]; } else { $installedversion = get_config($component, 'version'); } if (empty($installedversion)) { // new installation return true; } else { if ($installedversion < $plugin->version) { // upgrade return true; } } } } return false; }
*/ require_once '../../config.php'; require_once $CFG->dirroot . '/lib/adminlib.php'; require_once $CFG->dirroot . '/local/datahub/lib/rlip_dataplugin.class.php'; //permissions checking require_login(); $context = context_system::instance(); require_capability('moodle/site:config', $context); //header admin_externalpage_setup('rlipsettingplugins'); $PAGE->requires->css('/local/datahub/styles.css'); echo $OUTPUT->header(); //the types of plugins we are considering $plugintypes = array('dhimport', 'dhexport'); //lookup for the directory paths for plugins $directories = get_plugin_types(); foreach ($plugintypes as $plugintype) { //plugin header echo $OUTPUT->box_start('generalbox pluginspageheading'); print_string("{$plugintype}plugins", 'local_datahub'); echo $OUTPUT->box_end(); //initialize table $table = new html_table(); $table->head = array(get_string('name'), get_string('settings'), get_string('schedule'), get_string('runmanually', 'local_datahub')); $table->align = array('left', 'center', 'center', 'center'); $table->size = array('60%', '13%', '13%', '13%'); $table->data = array(); $table->width = '40%'; //obtain plugins and iterate through them $plugins = get_plugin_list($plugintype); //base directory
/** * Given a specific page type, parent context and currect context, return all the page type patterns * that might be used by this block. * * @param string $pagetype for example 'course-view-weeks' or 'mod-quiz-view'. * @param stdClass $parentcontext Block's parent context * @param stdClass $currentcontext Current context of block * @return array an array of all the page type patterns that might match this page type. */ function generate_page_type_patterns($pagetype, $parentcontext = null, $currentcontext = null) { global $CFG; $bits = explode('-', $pagetype); $core = get_core_subsystems(); $plugins = get_plugin_types(); //progressively strip pieces off the page type looking for a match $componentarray = null; for ($i = count($bits); $i > 0; $i--) { $possiblecomponentarray = array_slice($bits, 0, $i); $possiblecomponent = implode('', $possiblecomponentarray); // Check to see if the component is a core component if (array_key_exists($possiblecomponent, $core) && !empty($core[$possiblecomponent])) { $libfile = $CFG->dirroot . '/' . $core[$possiblecomponent] . '/lib.php'; if (file_exists($libfile)) { require_once $libfile; $function = $possiblecomponent . '_page_type_list'; if (function_exists($function)) { if ($patterns = $function($pagetype, $parentcontext, $currentcontext)) { break; } } } } //check the plugin directory and look for a callback if (array_key_exists($possiblecomponent, $plugins) && !empty($plugins[$possiblecomponent])) { //We've found a plugin type. Look for a plugin name by getting the next section of page type if (count($bits) > $i) { $pluginname = $bits[$i]; $directory = get_plugin_directory($possiblecomponent, $pluginname); if (!empty($directory)) { $libfile = $directory . '/lib.php'; if (file_exists($libfile)) { require_once $libfile; $function = $possiblecomponent . '_' . $pluginname . '_page_type_list'; if (!function_exists($function)) { $function = $pluginname . '_page_type_list'; } if (function_exists($function)) { if ($patterns = $function($pagetype, $parentcontext, $currentcontext)) { break; } } } } } //we'll only get to here if we still don't have any patterns //the plugin type may have a callback $directory = get_plugin_directory($possiblecomponent, null); if (!empty($directory)) { $libfile = $directory . '/lib.php'; if (file_exists($libfile)) { require_once $libfile; $function = $possiblecomponent . '_page_type_list'; if (function_exists($function)) { if ($patterns = $function($pagetype, $parentcontext, $currentcontext)) { break; } } } } } } if (empty($patterns)) { $patterns = default_page_type_list($pagetype, $parentcontext, $currentcontext); } // Ensure that the * pattern is always available if editing block 'at distance', so // we always can 'bring back' it to the original context. MDL-30340 if ((!isset($currentcontext) or !isset($parentcontext) or $currentcontext->id != $parentcontext->id) && !isset($patterns['*'])) { // TODO: We could change the string here, showing its 'bring back' meaning $patterns['*'] = get_string('page-x', 'pagetype'); } return $patterns; }
/** * Returns a tree of known plugins and information about them * * @param bool $disablecache force reload, cache can be used otherwise * @return array */ public function get_plugins($disablecache = false) { if ($disablecache or is_null($this->pluginsinfo)) { $this->pluginsinfo = array(); $plugintypes = get_plugin_types(); foreach ($plugintypes as $plugintype => $plugintyperootdir) { if (in_array($plugintype, array('base', 'general'))) { throw new coding_exception('Illegal usage of reserved word for plugin type'); } if (class_exists('plugintype_' . $plugintype)) { $plugintypeclass = 'plugintype_' . $plugintype; } else { $plugintypeclass = 'plugintype_general'; } if (!in_array('plugintype_interface', class_implements($plugintypeclass))) { throw new coding_exception('Class ' . $plugintypeclass . ' must implement plugintype_interface'); } $plugins = call_user_func(array($plugintypeclass, 'get_plugins'), $plugintype, $plugintyperootdir, $plugintypeclass); $this->pluginsinfo[$plugintype] = $plugins; } } return $this->pluginsinfo; }
/** * This function will generate the PHP code needed to * implement the upgrade_xxxx_savepoint() php calls in * upgrade code generated from the editor. It's used by * the view_structure_php and view_table_php actions * * @param xmldb_structure structure object containing all the info * @return string PHP code to be used to mark a reached savepoint */ function upgrade_savepoint_php($structure) { $path = $structure->getPath(); // Trim "db" from path $path = dirname($path); // Get pluginname, plugindir and plugintype $pluginname = basename($path); if ($path == 'lib') { // exception for lib (not proper plugin) $plugindir = 'lib'; $plugintype = 'lib'; } else { // rest of plugins // TODO: this is not nice and may fail, plugintype should be passed around somehow instead $plugintypes = get_plugin_types(false); $plugindir = dirname($path); $plugindir = str_replace('\\', '/', $plugindir); $plugintype = array_search($plugindir, $plugintypes); } $result = ''; switch ($plugintype) { case 'lib': // has own savepoint function $result = XMLDB_LINEFEED . ' // Main savepoint reached' . XMLDB_LINEFEED . ' upgrade_main_savepoint(true, XXXXXXXXXX);' . XMLDB_LINEFEED; break; case 'mod': // has own savepoint function $result = XMLDB_LINEFEED . ' // ' . $pluginname . ' savepoint reached' . XMLDB_LINEFEED . ' upgrade_mod_savepoint(true, XXXXXXXXXX, ' . "'{$pluginname}'" . ');' . XMLDB_LINEFEED; break; case 'block': // has own savepoint function $result = XMLDB_LINEFEED . ' // ' . $pluginname . ' savepoint reached' . XMLDB_LINEFEED . ' upgrade_block_savepoint(true, XXXXXXXXXX, ' . "'{$pluginname}'" . ');' . XMLDB_LINEFEED; break; default: // rest of plugins $result = XMLDB_LINEFEED . ' // ' . $pluginname . ' savepoint reached' . XMLDB_LINEFEED . ' upgrade_plugin_savepoint(true, XXXXXXXXXX, ' . "'{$plugintype}'" . ', ' . "'{$pluginname}'" . ');' . XMLDB_LINEFEED; } return $result; }
/** * Upgrade/install other parts of moodle * @param bool $verbose * @return void, may throw exception */ function upgrade_noncore($verbose) { global $CFG; raise_memory_limit(MEMORY_EXTRA); // upgrade all plugins types try { $plugintypes = get_plugin_types(); foreach ($plugintypes as $type=>$location) { upgrade_plugins($type, 'print_upgrade_part_start', 'print_upgrade_part_end', $verbose); } } catch (Exception $ex) { upgrade_handle_exception($ex); } }
/** * Builds dirroot/phpunit.xml and dataroot/phpunit/webrunner.xml files using defaults from /phpunit.xml.dist * @static * @return bool true means main config file created, false means only dataroot file created */ public static function build_config_file() { global $CFG; $template = ' <testsuite name="@component@ test suite"> <directory suffix="_test.php">@dir@</directory> </testsuite>'; $data = file_get_contents("{$CFG->dirroot}/phpunit.xml.dist"); $suites = ''; $plugintypes = get_plugin_types(); ksort($plugintypes); foreach ($plugintypes as $type => $unused) { $plugs = get_plugin_list($type); ksort($plugs); foreach ($plugs as $plug => $fullplug) { if (!file_exists("{$fullplug}/tests/")) { continue; } $dir = substr($fullplug, strlen($CFG->dirroot) + 1); $dir .= '/tests'; $component = $type . '_' . $plug; $suite = str_replace('@component@', $component, $template); $suite = str_replace('@dir@', $dir, $suite); $suites .= $suite; } } $data = preg_replace('|<!--@plugin_suites_start@-->.*<!--@plugin_suites_end@-->|s', $suites, $data, 1); $result = false; if (is_writable($CFG->dirroot)) { if ($result = file_put_contents("{$CFG->dirroot}/phpunit.xml", $data)) { testing_fix_file_permissions("{$CFG->dirroot}/phpunit.xml"); } } // relink - it seems that xml:base does not work in phpunit xml files, remove this nasty hack if you find a way to set xml base for relative refs $data = str_replace('lib/phpunit/', $CFG->dirroot . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'phpunit' . DIRECTORY_SEPARATOR, $data); $data = preg_replace('|<directory suffix="_test.php">([^<]+)</directory>|', '<directory suffix="_test.php">' . $CFG->dirroot . (DIRECTORY_SEPARATOR === '\\' ? '\\\\' : DIRECTORY_SEPARATOR) . '$1</directory>', $data); file_put_contents("{$CFG->dataroot}/phpunit/webrunner.xml", $data); testing_fix_file_permissions("{$CFG->dataroot}/phpunit/webrunner.xml"); return (bool) $result; }
/** * Prepares a renderable widget to execute installation of an available update. * * @param available_update_info $info component version to deploy * @param moodle_url $returnurl URL to return after the installation execution * @return renderable */ public function make_execution_widget(available_update_info $info, moodle_url $returnurl = null) { global $CFG; if (!$this->initialized()) { throw new coding_exception('Illegal method call - deployer not initialized.'); } $pluginrootpaths = get_plugin_types(true); list($plugintype, $pluginname) = normalize_component($info->component); if (empty($pluginrootpaths[$plugintype])) { throw new coding_exception('Unknown plugin type root location', $plugintype); } list($passfile, $password) = $this->prepare_authorization(); if (is_null($returnurl)) { $returnurl = new moodle_url('/admin'); } else { $returnurl = $returnurl; } $params = array('upgrade' => true, 'type' => $plugintype, 'name' => $pluginname, 'typeroot' => $pluginrootpaths[$plugintype], 'package' => $info->download, 'md5' => $info->downloadmd5, 'dataroot' => $CFG->dataroot, 'dirroot' => $CFG->dirroot, 'passfile' => $passfile, 'password' => $password, 'returnurl' => $returnurl->out(false)); if (!empty($CFG->proxyhost)) { // MDL-36973 - Beware - we should call just !is_proxybypass() here. But currently, our // cURL wrapper class does not do it. So, to have consistent behaviour, we pass proxy // setting regardless the $CFG->proxybypass setting. Once the {@link curl} class is // fixed, the condition should be amended. if (true or !is_proxybypass($info->download)) { if (empty($CFG->proxyport)) { $params['proxy'] = $CFG->proxyhost; } else { $params['proxy'] = $CFG->proxyhost . ':' . $CFG->proxyport; } if (!empty($CFG->proxyuser) and !empty($CFG->proxypassword)) { $params['proxyuserpwd'] = $CFG->proxyuser . ':' . $CFG->proxypassword; } if (!empty($CFG->proxytype)) { $params['proxytype'] = $CFG->proxytype; } } } $widget = new single_button(new moodle_url('/mdeploy.php', $params), get_string('updateavailableinstall', 'core_admin'), 'post'); return $widget; }
public function test_deprecated_get_plugin_types() { global $CFG; $plugintypes = core_component::get_plugin_types(); $this->assertSame($plugintypes, get_plugin_types()); $this->assertSame($plugintypes, get_plugin_types(true)); $realplugintypes = get_plugin_types(false); $this->assertDebuggingCalled(); foreach ($plugintypes as $plugintype => $fulldir) { $this->assertSame($fulldir, $CFG->dirroot . '/' . $realplugintypes[$plugintype]); } }
/** * Determine the module metadata for all moodle YUI modules. * * This works through all modules capable of serving YUI modules, and attempts to get * metadata for each of those modules. * * @return Array of module metadata */ private function get_moodle_metadata() { $moodlemodules = array(); // Core isn't a plugin type or subsystem - handle it seperately. if ($module = $this->get_moodle_path_metadata(get_component_directory('core'))) { $moodlemodules = array_merge($moodlemodules, $module); } // Handle other core subsystems. $subsystems = get_core_subsystems(); foreach ($subsystems as $subsystem => $path) { if (is_null($path)) { continue; } $path = get_component_directory($subsystem); if ($module = $this->get_moodle_path_metadata($path)) { $moodlemodules = array_merge($moodlemodules, $module); } } // And finally the plugins. $plugintypes = get_plugin_types(); foreach ($plugintypes as $plugintype => $pathroot) { $pluginlist = get_plugin_list($plugintype); foreach ($pluginlist as $plugin => $path) { if ($module = $this->get_moodle_path_metadata($path)) { $moodlemodules = array_merge($moodlemodules, $module); } } } return $moodlemodules; }
/** * Given a specific page type, parent context and currect context, return all the page type patterns * that might be used by this block. * * @param string $pagetype for example 'course-view-weeks' or 'mod-quiz-view'. * @param stdClass $parentcontext Block's parent context * @param stdClass $currentcontext Current context of block * @return array an array of all the page type patterns that might match this page type. */ function generate_page_type_patterns($pagetype, $parentcontext = null, $currentcontext = null) { global $CFG; $bits = explode('-', $pagetype); $core = get_core_subsystems(); $plugins = get_plugin_types(); //progressively strip pieces off the page type looking for a match $componentarray = null; for ($i = count($bits); $i > 0; $i--) { $possiblecomponentarray = array_slice($bits, 0, $i); $possiblecomponent = implode('', $possiblecomponentarray); // Check to see if the component is a core component if (array_key_exists($possiblecomponent, $core) && !empty($core[$possiblecomponent])) { $libfile = $CFG->dirroot . '/' . $core[$possiblecomponent] . '/lib.php'; if (file_exists($libfile)) { require_once $libfile; $function = $possiblecomponent . '_page_type_list'; if (function_exists($function)) { if ($patterns = $function($pagetype, $parentcontext, $currentcontext)) { break; } } } } //check the plugin directory and look for a callback if (array_key_exists($possiblecomponent, $plugins) && !empty($plugins[$possiblecomponent])) { //We've found a plugin type. Look for a plugin name by getting the next section of page type if (count($bits) > $i) { $pluginname = $bits[$i]; $directory = get_plugin_directory($possiblecomponent, $pluginname); if (!empty($directory)) { $libfile = $directory . '/lib.php'; if (file_exists($libfile)) { require_once $libfile; $function = $pluginname . '_page_type_list'; if (function_exists($function)) { if ($patterns = $function($pagetype, $parentcontext, $currentcontext)) { break; } } } } } //we'll only get to here if we still don't have any patterns //the plugin type may have a callback $directory = get_plugin_directory($possiblecomponent, null); if (!empty($directory)) { $libfile = $directory . '/lib.php'; if (file_exists($libfile)) { require_once $libfile; $function = $possiblecomponent . '_page_type_list'; if (function_exists($function)) { if ($patterns = $function($pagetype, $parentcontext, $currentcontext)) { break; } } } } } } if (empty($patterns)) { $patterns = default_page_type_list($pagetype, $parentcontext, $currentcontext); } return $patterns; }
/** * Returns list of all directories where we expect install.xml files * @return array Array of paths */ function get_db_directories() { global $CFG; $dbdirs = array(); /// First, the main one (lib/db) $dbdirs[] = $CFG->libdir . '/db'; /// Then, all the ones defined by get_plugin_types() $plugintypes = get_plugin_types(); foreach ($plugintypes as $plugintype => $pluginbasedir) { if ($plugins = get_plugin_list($plugintype)) { foreach ($plugins as $plugin => $plugindir) { $dbdirs[] = $plugindir . '/db'; } } } return $dbdirs; }
/** * Add plugin structure to any element in the structure restore tree * * @param string $plugintype type of plugin as defined by get_plugin_types() * @param restore_path_element $element element in the structure restore tree that * we are going to add plugin information to */ protected function add_plugin_structure($plugintype, $element) { global $CFG; // Check the requested plugintype is a valid one if (!array_key_exists($plugintype, get_plugin_types($plugintype))) { throw new restore_step_exception('incorrect_plugin_type', $plugintype); } // Get all the restore path elements, looking across all the plugin dirs $pluginsdirs = get_plugin_list($plugintype); foreach ($pluginsdirs as $name => $pluginsdir) { // We need to add also backup plugin classes on restore, they may contain // some stuff used both in backup & restore $backupclassname = 'backup_' . $plugintype . '_' . $name . '_plugin'; $backupfile = $pluginsdir . '/backup/moodle2/' . $backupclassname . '.class.php'; if (file_exists($backupfile)) { require_once $backupfile; } // Now add restore plugin classes and prepare stuff $restoreclassname = 'restore_' . $plugintype . '_' . $name . '_plugin'; $restorefile = $pluginsdir . '/backup/moodle2/' . $restoreclassname . '.class.php'; if (file_exists($restorefile)) { require_once $restorefile; $restoreplugin = new $restoreclassname($plugintype, $name, $this); // Add plugin paths to the step $this->prepare_pathelements($restoreplugin->define_plugin_structure($element)); } } }