/** * Do not instantinate this directly, use {@link grading_manager::get_controller()} * * @param stdClass $context the context of the form * @param string $component the frankenstyle name of the component * @param string $area the name of the gradable area * @param int $areaid the id of the gradable area record */ public function __construct(stdClass $context, $component, $area, $areaid) { global $DB; $this->context = $context; list($type, $name) = core_component::normalize_component($component); $this->component = $type . '_' . $name; $this->area = $area; $this->areaid = $areaid; $this->load_definition(); }
/** * This function will render one beautiful table with all the scheduled tasks. * * @param \core\task\scheduled_task[] $tasks - list of all scheduled tasks. * @return string HTML to output. */ public function scheduled_tasks_table($tasks) { global $CFG; $table = new html_table(); $table->head = array(get_string('name'), get_string('component', 'tool_task'), get_string('edit'), get_string('lastruntime', 'tool_task'), get_string('nextruntime', 'tool_task'), get_string('taskscheduleminute', 'tool_task'), get_string('taskschedulehour', 'tool_task'), get_string('taskscheduleday', 'tool_task'), get_string('taskscheduledayofweek', 'tool_task'), get_string('taskschedulemonth', 'tool_task'), get_string('faildelay', 'tool_task'), get_string('default', 'tool_task')); $table->attributes['class'] = 'admintable generaltable'; $data = array(); $yes = get_string('yes'); $no = get_string('no'); $never = get_string('never'); $asap = get_string('asap', 'tool_task'); $disabled = get_string('disabled', 'tool_task'); foreach ($tasks as $task) { $customised = $task->is_customised() ? $no : $yes; $lastrun = $task->get_last_run_time() ? userdate($task->get_last_run_time()) : $never; $nextrun = $task->get_next_run_time(); if ($task->get_disabled()) { $nextrun = $disabled; } else { if ($nextrun > time()) { $nextrun = userdate($nextrun); } else { $nextrun = $asap; } } if (empty($CFG->preventscheduledtaskchanges)) { $configureurl = new moodle_url('/admin/tool/task/scheduledtasks.php', array('action' => 'edit', 'task' => get_class($task))); $editlink = $this->action_icon($configureurl, new pix_icon('t/edit', get_string('edittaskschedule', 'tool_task', $task->get_name()))); } else { $editlink = $this->render(new pix_icon('t/locked', get_string('scheduledtaskchangesdisabled', 'tool_task'))); } $namecell = new html_table_cell($task->get_name() . "\n" . html_writer::tag('span', '\\' . get_class($task), array('class' => 'task-class'))); $namecell->header = true; $component = $task->get_component(); list($type, $plugin) = core_component::normalize_component($component); if ($type === 'core') { $componentcell = new html_table_cell(get_string('corecomponent', 'tool_task')); } else { if ($plugininfo = core_plugin_manager::instance()->get_plugin_info($component)) { $plugininfo->init_display_name(); $componentcell = new html_table_cell($plugininfo->displayname); } else { $componentcell = new html_table_cell($component); } } $row = new html_table_row(array($namecell, $componentcell, new html_table_cell($editlink), new html_table_cell($lastrun), new html_table_cell($nextrun), new html_table_cell($task->get_minute()), new html_table_cell($task->get_hour()), new html_table_cell($task->get_day()), new html_table_cell($task->get_day_of_week()), new html_table_cell($task->get_month()), new html_table_cell($task->get_fail_delay()), new html_table_cell($customised))); if ($task->get_disabled()) { $row->attributes['class'] = 'disabled'; } $data[] = $row; } $table->data = $data; return html_writer::table($table); }
/** * Get the absolute install directory path within Moodle. * * @param string $component Moodle component, EG: mod_forum * * @return string Absolute path, EG: /path/to/mod/forum */ public function getComponentInstallDirectory($component) { $this->requireConfig(); /* @noinspection PhpUndefinedClassInspection */ list($type, $name) = \core_component::normalize_component($component); /* @noinspection PhpUndefinedClassInspection */ $types = \core_component::get_plugin_types(); if (!array_key_exists($type, $types)) { throw new \InvalidArgumentException(sprintf('The component %s has an unknown plugin type of %s', $component, $type)); } return $types[$type] . '/' . $name; }
/** * Return generator for given plugin or component. * @param string $component the component name, e.g. 'mod_forum' or 'core_question'. * @return component_generator_base or rather an instance of the appropriate subclass. */ public function get_plugin_generator($component) { list($type, $plugin) = core_component::normalize_component($component); $cleancomponent = $type . '_' . $plugin; if ($cleancomponent != $component) { debugging("Please specify the component you want a generator for as " . "{$cleancomponent}, not {$component}.", DEBUG_DEVELOPER); $component = $cleancomponent; } if (isset($this->generators[$component])) { return $this->generators[$component]; } $dir = core_component::get_component_directory($component); $lib = $dir . '/tests/generator/lib.php'; if (!$dir || !is_readable($lib)) { throw new coding_exception("Component {$component} does not support " . "generators yet. Missing tests/generator/lib.php."); } include_once $lib; $classname = $component . '_generator'; if (!class_exists($classname)) { throw new coding_exception("Component {$component} does not support " . "data generators yet. Class {$classname} not found."); } $this->generators[$component] = new $classname($this); return $this->generators[$component]; }
function definition() { $mform = $this->_form; $current = $this->_customdata['current']; $mform->addElement('header', 'filtersettings', get_string('filter', 'tool_customlang')); // Component $options = array(); foreach (tool_customlang_utils::list_components() as $component => $normalized) { list($type, $plugin) = core_component::normalize_component($normalized); if ($type == 'core' and is_null($plugin)) { $plugin = 'moodle'; } $options[$type][$normalized] = $component . '.php'; } $mform->addElement('selectgroups', 'component', get_string('filtercomponent', 'tool_customlang'), $options, array('multiple' => 'multiple', 'size' => 7)); // Customized only $mform->addElement('advcheckbox', 'customized', get_string('filtercustomized', 'tool_customlang')); $mform->setType('customized', PARAM_BOOL); $mform->setDefault('customized', 0); // Only helps $mform->addElement('advcheckbox', 'helps', get_string('filteronlyhelps', 'tool_customlang')); $mform->setType('helps', PARAM_BOOL); $mform->setDefault('helps', 0); // Modified only $mform->addElement('advcheckbox', 'modified', get_string('filtermodified', 'tool_customlang')); $mform->setType('modified', PARAM_BOOL); $mform->setDefault('modified', 0); // Substring $mform->addElement('text', 'substring', get_string('filtersubstring', 'tool_customlang')); $mform->setType('substring', PARAM_RAW); // String identifier $mform->addElement('text', 'stringid', get_string('filterstringid', 'tool_customlang')); $mform->setType('stringid', PARAM_STRINGID); // Show strings - submit button $mform->addElement('submit', 'submit', get_string('filtershowstrings', 'tool_customlang')); }
/** * upgrades the mnet rpc definitions for the given component. * this method doesn't return status, an exception will be thrown in the case of an error * * @param string $component the plugin to upgrade, eg auth_mnet */ function upgrade_plugin_mnet_functions($component) { global $DB, $CFG; list($type, $plugin) = core_component::normalize_component($component); $path = core_component::get_plugin_directory($type, $plugin); $publishes = array(); $subscribes = array(); if (file_exists($path . '/db/mnet.php')) { require_once $path . '/db/mnet.php'; // $publishes comes from this file } if (empty($publishes)) { $publishes = array(); // still need this to be able to disable stuff later } if (empty($subscribes)) { $subscribes = array(); // still need this to be able to disable stuff later } static $servicecache = array(); // rekey an array based on the rpc method for easy lookups later $publishmethodservices = array(); $subscribemethodservices = array(); foreach ($publishes as $servicename => $service) { if (is_array($service['methods'])) { foreach ($service['methods'] as $methodname) { $service['servicename'] = $servicename; $publishmethodservices[$methodname][] = $service; } } } // Disable functions that don't exist (any more) in the source // Should these be deleted? What about their permissions records? foreach ($DB->get_records('mnet_rpc', array('pluginname' => $plugin, 'plugintype' => $type), 'functionname ASC ') as $rpc) { if (!array_key_exists($rpc->functionname, $publishmethodservices) && $rpc->enabled) { $DB->set_field('mnet_rpc', 'enabled', 0, array('id' => $rpc->id)); } else { if (array_key_exists($rpc->functionname, $publishmethodservices) && !$rpc->enabled) { $DB->set_field('mnet_rpc', 'enabled', 1, array('id' => $rpc->id)); } } } // reflect all the services we're publishing and save them require_once $CFG->dirroot . '/lib/zend/Zend/Server/Reflection.php'; static $cachedclasses = array(); // to store reflection information in foreach ($publishes as $service => $data) { $f = $data['filename']; $c = $data['classname']; foreach ($data['methods'] as $method) { $dataobject = new stdClass(); $dataobject->plugintype = $type; $dataobject->pluginname = $plugin; $dataobject->enabled = 1; $dataobject->classname = $c; $dataobject->filename = $f; if (is_string($method)) { $dataobject->functionname = $method; } else { if (is_array($method)) { // wants to override file or class $dataobject->functionname = $method['method']; $dataobject->classname = $method['classname']; $dataobject->filename = $method['filename']; } } $dataobject->xmlrpcpath = $type . '/' . $plugin . '/' . $dataobject->filename . '/' . $method; $dataobject->static = false; require_once $path . '/' . $dataobject->filename; $functionreflect = null; // slightly different ways to get this depending on whether it's a class method or a function if (!empty($dataobject->classname)) { if (!class_exists($dataobject->classname)) { throw new moodle_exception('installnosuchmethod', 'mnet', '', (object) array('method' => $dataobject->functionname, 'class' => $dataobject->classname)); } $key = $dataobject->filename . '|' . $dataobject->classname; if (!array_key_exists($key, $cachedclasses)) { // look to see if we've already got a reflection object try { $cachedclasses[$key] = Zend_Server_Reflection::reflectClass($dataobject->classname); } catch (Zend_Server_Reflection_Exception $e) { // catch these and rethrow them to something more helpful throw new moodle_exception('installreflectionclasserror', 'mnet', '', (object) array('method' => $dataobject->functionname, 'class' => $dataobject->classname, 'error' => $e->getMessage())); } } $r =& $cachedclasses[$key]; if (!$r->hasMethod($dataobject->functionname)) { throw new moodle_exception('installnosuchmethod', 'mnet', '', (object) array('method' => $dataobject->functionname, 'class' => $dataobject->classname)); } // stupid workaround for zend not having a getMethod($name) function $ms = $r->getMethods(); foreach ($ms as $m) { if ($m->getName() == $dataobject->functionname) { $functionreflect = $m; break; } } $dataobject->static = (int) $functionreflect->isStatic(); } else { if (!function_exists($dataobject->functionname)) { throw new moodle_exception('installnosuchfunction', 'mnet', '', (object) array('method' => $dataobject->functionname, 'file' => $dataobject->filename)); } try { $functionreflect = Zend_Server_Reflection::reflectFunction($dataobject->functionname); } catch (Zend_Server_Reflection_Exception $e) { // catch these and rethrow them to something more helpful throw new moodle_exception('installreflectionfunctionerror', 'mnet', '', (object) array('method' => $dataobject->functionname, '' => $dataobject->filename, 'error' => $e->getMessage())); } } $dataobject->profile = serialize(admin_mnet_method_profile($functionreflect)); $dataobject->help = $functionreflect->getDescription(); if ($record_exists = $DB->get_record('mnet_rpc', array('xmlrpcpath' => $dataobject->xmlrpcpath))) { $dataobject->id = $record_exists->id; $dataobject->enabled = $record_exists->enabled; $DB->update_record('mnet_rpc', $dataobject); } else { $dataobject->id = $DB->insert_record('mnet_rpc', $dataobject, true); } // TODO this API versioning must be reworked, here the recently processed method // sets the service API which may not be correct foreach ($publishmethodservices[$dataobject->functionname] as $service) { if ($serviceobj = $DB->get_record('mnet_service', array('name' => $service['servicename']))) { $serviceobj->apiversion = $service['apiversion']; $DB->update_record('mnet_service', $serviceobj); } else { $serviceobj = new stdClass(); $serviceobj->name = $service['servicename']; $serviceobj->description = empty($service['description']) ? '' : $service['description']; $serviceobj->apiversion = $service['apiversion']; $serviceobj->offer = 1; $serviceobj->id = $DB->insert_record('mnet_service', $serviceobj); } $servicecache[$service['servicename']] = $serviceobj; if (!$DB->record_exists('mnet_service2rpc', array('rpcid' => $dataobject->id, 'serviceid' => $serviceobj->id))) { $obj = new stdClass(); $obj->rpcid = $dataobject->id; $obj->serviceid = $serviceobj->id; $DB->insert_record('mnet_service2rpc', $obj, true); } } } } // finished with methods we publish, now do subscribable methods foreach ($subscribes as $service => $methods) { if (!array_key_exists($service, $servicecache)) { if (!($serviceobj = $DB->get_record('mnet_service', array('name' => $service)))) { debugging("TODO: skipping unknown service {$service} - somebody needs to fix MDL-21993"); continue; } $servicecache[$service] = $serviceobj; } else { $serviceobj = $servicecache[$service]; } foreach ($methods as $method => $xmlrpcpath) { if (!($rpcid = $DB->get_field('mnet_remote_rpc', 'id', array('xmlrpcpath' => $xmlrpcpath)))) { $remoterpc = (object) array('functionname' => $method, 'xmlrpcpath' => $xmlrpcpath, 'plugintype' => $type, 'pluginname' => $plugin, 'enabled' => 1); $rpcid = $remoterpc->id = $DB->insert_record('mnet_remote_rpc', $remoterpc, true); } if (!$DB->record_exists('mnet_remote_service2rpc', array('rpcid' => $rpcid, 'serviceid' => $serviceobj->id))) { $obj = new stdClass(); $obj->rpcid = $rpcid; $obj->serviceid = $serviceobj->id; $DB->insert_record('mnet_remote_service2rpc', $obj, true); } $subscribemethodservices[$method][] = $service; } } foreach ($DB->get_records('mnet_remote_rpc', array('pluginname' => $plugin, 'plugintype' => $type), 'functionname ASC ') as $rpc) { if (!array_key_exists($rpc->functionname, $subscribemethodservices) && $rpc->enabled) { $DB->set_field('mnet_remote_rpc', 'enabled', 0, array('id' => $rpc->id)); } else { if (array_key_exists($rpc->functionname, $subscribemethodservices) && !$rpc->enabled) { $DB->set_field('mnet_remote_rpc', 'enabled', 1, array('id' => $rpc->id)); } } } return true; }
/** * For a given module name, return the possible class names * that defines the renderer interface for that module. * * Newer auto-loaded class names are returned as well as the old style _renderable classnames. * * Also, if it exists, include the renderer.php file for that module, so * the class definition of the default renderer has been loaded. * * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. * @param string $subtype optional subtype such as 'news' resulting to: * '\mod_forum\output\news_renderer' * or '\mod_forum\output\news\renderer' * or non-autoloaded 'mod_forum_news' * @return array[] Each element of the array is an array with keys: * classname - The class name to search * autoloaded - Does this classname assume autoloading? * validwithprefix - Is this class name valid when a prefix is added to it? * validwithoutprefix - Is this class name valid when no prefix is added to it? * @throws coding_exception */ protected function standard_renderer_classnames($component, $subtype = null) { global $CFG; // Needed in included files. $classnames = array(); // Standardize component name ala frankenstyle. list($plugin, $type) = core_component::normalize_component($component); if ($type === null) { $component = $plugin; } else { $component = $plugin . '_' . $type; } if ($component !== 'core') { // Renderers are stored in renderer.php files. if (!($compdirectory = core_component::get_component_directory($component))) { throw new coding_exception('Invalid component specified in renderer request', $component); } $rendererfile = $compdirectory . '/renderer.php'; if (file_exists($rendererfile)) { include_once $rendererfile; } } else { if (!empty($subtype)) { $coresubsystems = core_component::get_core_subsystems(); if (!array_key_exists($subtype, $coresubsystems)) { // There may be nulls. throw new coding_exception('Invalid core subtype "' . $subtype . '" in renderer request', $subtype); } if ($coresubsystems[$subtype]) { $rendererfile = $coresubsystems[$subtype] . '/renderer.php'; if (file_exists($rendererfile)) { include_once $rendererfile; } } } } if (empty($subtype)) { // Theme specific auto-loaded name (only valid when prefixed with the theme name). $classnames[] = array('validwithprefix' => true, 'validwithoutprefix' => false, 'autoloaded' => true, 'classname' => '\\output\\' . $component . '_renderer'); // Standard autoloaded plugin name (not valid with a prefix). $classnames[] = array('validwithprefix' => false, 'validwithoutprefix' => true, 'autoloaded' => true, 'classname' => '\\' . $component . '\\output\\renderer'); // Legacy class name - (valid with or without a prefix). $classnames[] = array('validwithprefix' => true, 'validwithoutprefix' => true, 'autoloaded' => false, 'classname' => $component . '_renderer'); } else { // Theme specific auto-loaded name (only valid when prefixed with the theme name). $classnames[] = array('validwithprefix' => true, 'validwithoutprefix' => false, 'autoloaded' => true, 'classname' => '\\output\\' . $component . '\\' . $subtype . '_renderer'); // Version of the above with subtype being a namespace level on it's own. $classnames[] = array('validwithprefix' => true, 'validwithoutprefix' => false, 'autoloaded' => true, 'classname' => '\\output\\' . $component . '\\' . $subtype . '\\renderer'); // Standard autoloaded plugin name (not valid with a prefix). $classnames[] = array('validwithprefix' => false, 'validwithoutprefix' => true, 'autoloaded' => true, 'classname' => '\\' . $component . '\\output\\' . $subtype . '_renderer'); // Version of the above with subtype being a namespace level on it's own. $classnames[] = array('validwithprefix' => false, 'validwithoutprefix' => true, 'autoloaded' => true, 'classname' => '\\' . $component . '\\output\\' . $subtype . '\\renderer'); // Legacy class name - (valid with or without a prefix). $classnames[] = array('validwithprefix' => true, 'validwithoutprefix' => true, 'autoloaded' => false, 'classname' => $component . '_' . $subtype . '_renderer'); } return $classnames; }
protected static function get_module_from_component($component) { list($type, $name) = \core_component::normalize_component($component); if ($type == 'mod') { return $name; } if ($type == 'assignsubmission') { return 'assign'; } return null; }
/** * Returns information about the known plugin, or null * * @param string $component frankenstyle component name. * @return \core\plugininfo\base|null the corresponding plugin information. */ public function get_plugin_info($component) { list($type, $name) = core_component::normalize_component($component); $plugins = $this->get_plugins_of_type($type); if (isset($plugins[$name])) { return $plugins[$name]; } else { return null; } }
/** * Returns the active providers for the user specified, based on capability * * @param int $userid id of user * @return array An array of message providers */ function message_get_providers_for_user($userid) { global $DB, $CFG; $providers = get_message_providers(); // Ensure user is not allowed to configure instantmessage if it is globally disabled. if (!$CFG->messaging) { foreach ($providers as $providerid => $provider) { if ($provider->name == 'instantmessage') { unset($providers[$providerid]); break; } } } // If the component is an enrolment plugin, check it is enabled foreach ($providers as $providerid => $provider) { list($type, $name) = core_component::normalize_component($provider->component); if ($type == 'enrol' && !enrol_is_enabled($name)) { unset($providers[$providerid]); } } // Now we need to check capabilities. We need to eliminate the providers // where the user does not have the corresponding capability anywhere. // Here we deal with the common simple case of the user having the // capability in the system context. That handles $CFG->defaultuserroleid. // For the remaining providers/capabilities, we need to do a more complex // query involving all overrides everywhere. $unsureproviders = array(); $unsurecapabilities = array(); $systemcontext = context_system::instance(); foreach ($providers as $providerid => $provider) { if (empty($provider->capability) || has_capability($provider->capability, $systemcontext, $userid)) { // The provider is relevant to this user. continue; } $unsureproviders[$providerid] = $provider; $unsurecapabilities[$provider->capability] = 1; unset($providers[$providerid]); } if (empty($unsureproviders)) { // More complex checks are not required. return $providers; } // Now check the unsure capabilities. list($capcondition, $params) = $DB->get_in_or_equal( array_keys($unsurecapabilities), SQL_PARAMS_NAMED); $params['userid'] = $userid; $sql = "SELECT DISTINCT rc.capability, 1 FROM {role_assignments} ra JOIN {context} actx ON actx.id = ra.contextid JOIN {role_capabilities} rc ON rc.roleid = ra.roleid JOIN {context} cctx ON cctx.id = rc.contextid WHERE ra.userid = :userid AND rc.capability $capcondition AND rc.permission > 0 AND (".$DB->sql_concat('actx.path', "'/'")." LIKE ".$DB->sql_concat('cctx.path', "'/%'"). " OR ".$DB->sql_concat('cctx.path', "'/'")." LIKE ".$DB->sql_concat('actx.path', "'/%'").")"; if (!empty($CFG->defaultfrontpageroleid)) { $frontpagecontext = context_course::instance(SITEID); list($capcondition2, $params2) = $DB->get_in_or_equal( array_keys($unsurecapabilities), SQL_PARAMS_NAMED); $params = array_merge($params, $params2); $params['frontpageroleid'] = $CFG->defaultfrontpageroleid; $params['frontpagepathpattern'] = $frontpagecontext->path . '/'; $sql .= " UNION SELECT DISTINCT rc.capability, 1 FROM {role_capabilities} rc JOIN {context} cctx ON cctx.id = rc.contextid WHERE rc.roleid = :frontpageroleid AND rc.capability $capcondition2 AND rc.permission > 0 AND ".$DB->sql_concat('cctx.path', "'/'")." LIKE :frontpagepathpattern"; } $relevantcapabilities = $DB->get_records_sql_menu($sql, $params); // Add back any providers based on the detailed capability check. foreach ($unsureproviders as $providerid => $provider) { if (array_key_exists($provider->capability, $relevantcapabilities)) { $providers[$providerid] = $provider; } } return $providers; }
/** * This gets the mod/block/course/core etc strings. * * @param string $component * @param int $contextlevel * @return string|bool String is success, false if failed */ function get_component_string($component, $contextlevel) { if ($component === 'moodle' or $component === 'core') { switch ($contextlevel) { // TODO: this should probably use context level names instead case CONTEXT_SYSTEM: return get_string('coresystem'); case CONTEXT_USER: return get_string('users'); case CONTEXT_COURSECAT: return get_string('categories'); case CONTEXT_COURSE: return get_string('course'); case CONTEXT_MODULE: return get_string('activities'); case CONTEXT_BLOCK: return get_string('block'); default: print_error('unknowncontext'); } } list($type, $name) = core_component::normalize_component($component); $dir = core_component::get_plugin_directory($type, $name); if (!file_exists($dir)) { // plugin not installed, bad luck, there is no way to find the name return $component.' ???'; } switch ($type) { // TODO: this is really hacky, anyway it should be probably moved to lib/pluginlib.php case 'quiz': return get_string($name.':componentname', $component);// insane hack!!! case 'repository': return get_string('repository', 'repository').': '.get_string('pluginname', $component); case 'gradeimport': return get_string('gradeimport', 'grades').': '.get_string('pluginname', $component); case 'gradeexport': return get_string('gradeexport', 'grades').': '.get_string('pluginname', $component); case 'gradereport': return get_string('gradereport', 'grades').': '.get_string('pluginname', $component); case 'webservice': return get_string('webservice', 'webservice').': '.get_string('pluginname', $component); case 'block': return get_string('block').': '.get_string('pluginname', basename($component)); case 'mod': if (get_string_manager()->string_exists('pluginname', $component)) { return get_string('activity').': '.get_string('pluginname', $component); } else { return get_string('activity').': '.get_string('modulename', $component); } default: return get_string('pluginname', $component); } }
public function test_normalize_component() { // Moodle core. $this->assertSame(array('core', null), core_component::normalize_component('core')); $this->assertSame(array('core', null), core_component::normalize_component('moodle')); $this->assertSame(array('core', null), core_component::normalize_component('')); // Moodle core subsystems. $this->assertSame(array('core', 'admin'), core_component::normalize_component('admin')); $this->assertSame(array('core', 'admin'), core_component::normalize_component('core_admin')); $this->assertSame(array('core', 'admin'), core_component::normalize_component('moodle_admin')); // Activity modules and their subplugins. $this->assertSame(array('mod', 'workshop'), core_component::normalize_component('workshop')); $this->assertSame(array('mod', 'workshop'), core_component::normalize_component('mod_workshop')); $this->assertSame(array('workshopform', 'accumulative'), core_component::normalize_component('workshopform_accumulative')); $this->assertSame(array('mod', 'quiz'), core_component::normalize_component('quiz')); $this->assertSame(array('quiz', 'grading'), core_component::normalize_component('quiz_grading')); $this->assertSame(array('mod', 'data'), core_component::normalize_component('data')); $this->assertSame(array('datafield', 'checkbox'), core_component::normalize_component('datafield_checkbox')); // Other plugin types. $this->assertSame(array('auth', 'mnet'), core_component::normalize_component('auth_mnet')); $this->assertSame(array('enrol', 'self'), core_component::normalize_component('enrol_self')); $this->assertSame(array('block', 'html'), core_component::normalize_component('block_html')); $this->assertSame(array('block', 'mnet_hosts'), core_component::normalize_component('block_mnet_hosts')); $this->assertSame(array('local', 'amos'), core_component::normalize_component('local_amos')); $this->assertSame(array('local', 'admin'), core_component::normalize_component('local_admin')); // Unknown words without underscore are supposed to be activity modules. $this->assertSame(array('mod', 'whoonearthwouldcomewithsuchastupidnameofcomponent'), core_component::normalize_component('whoonearthwouldcomewithsuchastupidnameofcomponent')); // Module names can not contain underscores, this must be a subplugin. $this->assertSame(array('whoonearth', 'wouldcomewithsuchastupidnameofcomponent'), core_component::normalize_component('whoonearth_wouldcomewithsuchastupidnameofcomponent')); $this->assertSame(array('whoonearth', 'would_come_withsuchastupidnameofcomponent'), core_component::normalize_component('whoonearth_would_come_withsuchastupidnameofcomponent')); }
//for login and capability checks try { $autologinguest = true; $setwantsurltome = true; $preventredirect = true; require_login($course, $autologinguest, $cm, $setwantsurltome, $preventredirect); } catch (Exception $e) { if (isguestuser()) { rss_error('rsserrorguest'); } else { rss_error('rsserrorauth'); } } // Work out which component in Moodle we want (from the frankenstyle name) $componentdir = core_component::get_component_directory($componentname); list($type, $plugin) = core_component::normalize_component($componentname); // Call the component to check/update the feed and tell us the path to the cached file $pathname = null; if (file_exists($componentdir)) { require_once "{$componentdir}/rsslib.php"; $functionname = $plugin . '_rss_get_feed'; if (function_exists($functionname)) { // $pathname will be null if there was a problem (eg user doesn't have the necessary capabilities) // NOTE:the component providing the feed must do its own capability checks and security try { $pathname = $functionname($context, $args); } catch (Exception $e) { rss_error('rsserror'); } } }
/** * Adds log entry into upgrade_log table * * @param int $type UPGRADE_LOG_NORMAL, UPGRADE_LOG_NOTICE or UPGRADE_LOG_ERROR * @param string $plugin frankenstyle component name * @param string $info short description text of log entry * @param string $details long problem description * @param string $backtrace string used for errors only * @return void */ function upgrade_log($type, $plugin, $info, $details = null, $backtrace = null) { global $DB, $USER, $CFG; if (empty($plugin)) { $plugin = 'core'; } list($plugintype, $pluginname) = core_component::normalize_component($plugin); $component = is_null($pluginname) ? $plugintype : $plugintype . '_' . $pluginname; $backtrace = format_backtrace($backtrace, true); $currentversion = null; $targetversion = null; //first try to find out current version number if ($plugintype === 'core') { //main $currentversion = $CFG->version; $version = null; include "{$CFG->dirroot}/version.php"; $targetversion = $version; } else { $pluginversion = get_config($component, 'version'); if (!empty($pluginversion)) { $currentversion = $pluginversion; } $cd = core_component::get_component_directory($component); if (file_exists("{$cd}/version.php")) { $plugin = new stdClass(); $plugin->version = null; $module = $plugin; include "{$cd}/version.php"; $targetversion = $plugin->version; } } $log = new stdClass(); $log->type = $type; $log->plugin = $component; $log->version = $currentversion; $log->targetversion = $targetversion; $log->info = $info; $log->details = $details; $log->backtrace = $backtrace; $log->userid = $USER->id; $log->timemodified = time(); try { $DB->insert_record('upgrade_log', $log); } catch (Exception $ignored) { // possible during install or 2.0 upgrade } }
/** * Deletes all tag areas, collections and instances associated with the plugin. * * @param string $pluginname */ public static function uninstall($pluginname) { global $DB; list($a, $b) = core_component::normalize_component($pluginname); if (empty($b) || $a === 'core') { throw new coding_exception('Core component can not be uninstalled'); } $component = $a . '_' . $b; core_tag_tag::delete_instances($component); $DB->delete_records('tag_area', array('component' => $component)); $DB->delete_records('tag_coll', array('component' => $component)); cache::make('core', 'tags')->delete_many(array('tag_area', 'tag_coll')); }
/** * Get plugin name. * * @return string plugin name */ function getPluginName() { if ($this->plugin) { $manager = core_plugin_manager::instance(); list($plugintype, $pluginname) = core_component::normalize_component($this->plugin); return $manager->plugintype_name($plugintype) . ' / ' . $manager->plugin_name($this->plugin); } else { return ''; } }
/** * Get String returns a requested string * * @param string $identifier The identifier of the string to search for * @param string $component The module the string is associated with * @param string|object|array $a An object, string or number that can be used * within translation strings * @param string $lang moodle translation language, null means use current * @return string The String ! */ public function get_string($identifier, $component = '', $a = null, $lang = null) { global $CFG; $this->countgetstring++; // There are very many uses of these time formatting strings without the 'langconfig' component, // it would not be reasonable to expect that all of them would be converted during 2.0 migration. static $langconfigstrs = array('strftimedate' => 1, 'strftimedatefullshort' => 1, 'strftimedateshort' => 1, 'strftimedatetime' => 1, 'strftimedatetimeshort' => 1, 'strftimedaydate' => 1, 'strftimedaydatetime' => 1, 'strftimedayshort' => 1, 'strftimedaytime' => 1, 'strftimemonthyear' => 1, 'strftimerecent' => 1, 'strftimerecentfull' => 1, 'strftimetime' => 1); if (empty($component)) { if (isset($langconfigstrs[$identifier])) { $component = 'langconfig'; } else { $component = 'moodle'; } } if ($lang === null) { $lang = current_language(); } $string = $this->load_component_strings($component, $lang); if (!isset($string[$identifier])) { if ($component === 'pix' or $component === 'core_pix') { // This component contains only alt tags for emoticons, not all of them are supposed to be defined. return ''; } if ($identifier === 'parentlanguage' and ($component === 'langconfig' or $component === 'core_langconfig')) { // Identifier parentlanguage is a special string, undefined means use English if not defined. return 'en'; } // Do not rebuild caches here! // Devs need to learn to purge all caches after any change or disable $CFG->langstringcache. if (!isset($string[$identifier])) { // The string is still missing - should be fixed by developer. if ($CFG->debugdeveloper) { list($plugintype, $pluginname) = core_component::normalize_component($component); if ($plugintype === 'core') { $file = "lang/en/{$component}.php"; } else { if ($plugintype == 'mod') { $file = "mod/{$pluginname}/lang/en/{$pluginname}.php"; } else { $path = core_component::get_plugin_directory($plugintype, $pluginname); $file = "{$path}/lang/en/{$plugintype}_{$pluginname}.php"; } } debugging("Invalid get_string() identifier: '{$identifier}' or component '{$component}'. " . "Perhaps you are missing \$string['{$identifier}'] = ''; in {$file}?", DEBUG_DEVELOPER); } return "[[{$identifier}]]"; } } $string = $string[$identifier]; if ($a !== null) { // Process array's and objects (except lang_strings). if (is_array($a) or is_object($a) && !$a instanceof lang_string) { $a = (array) $a; $search = array(); $replace = array(); foreach ($a as $key => $value) { if (is_int($key)) { // We do not support numeric keys - sorry! continue; } if (is_array($value) or is_object($value) && !$value instanceof lang_string) { // We support just string or lang_string as value. continue; } $search[] = '{$a->' . $key . '}'; $replace[] = (string) $value; } if ($search) { $string = str_replace($search, $replace, $string); } } else { $string = str_replace('{$a}', (string) $a, $string); } } if ($CFG->debugdeveloper) { // Display a debugging message if sting exists but was deprecated. if ($this->string_deprecated($identifier, $component)) { list($plugintype, $pluginname) = core_component::normalize_component($component); $normcomponent = $pluginname ? $plugintype . '_' . $pluginname : $plugintype; debugging("String [{$identifier},{$normcomponent}] is deprecated. " . 'Either you should no longer be using that string, or the string has been incorrectly deprecated, in which case you should report this as a bug. ' . 'Please refer to https://docs.moodle.org/dev/String_deprecation', DEBUG_DEVELOPER); } } return $string; }
$form = $installer->get_installfromzip_form(); if ($form->is_cancelled()) { redirect($PAGE->url); } else { if ($data = $form->get_data()) { // Save the ZIP file into a temporary location. $jobid = md5(rand() . uniqid('', true)); $sourcedir = make_temp_directory('tool_installaddon/' . $jobid . '/source'); $zipfilename = $installer->save_installfromzip_file($form, $sourcedir); if (empty($data->plugintype)) { $versiondir = make_temp_directory('tool_installaddon/' . $jobid . '/version'); $detected = $installer->detect_plugin_component($sourcedir . '/' . $zipfilename, $versiondir); if (empty($detected)) { $form->require_explicit_plugintype(); } else { list($detectedtype, $detectedname) = core_component::normalize_component($detected); if ($detectedtype and $detectedname and $detectedtype !== 'core') { $data->plugintype = $detectedtype; } else { $form->require_explicit_plugintype(); } } } // Redirect to the validation page. if (!empty($data->plugintype)) { $nexturl = new moodle_url('/admin/tool/installaddon/validate.php', array('sesskey' => sesskey(), 'jobid' => $jobid, 'zip' => $zipfilename, 'type' => $data->plugintype, 'rootdir' => $data->rootdir)); redirect($nexturl); } } } // Output starts here.
/** * Normalize the component name using the "frankenstyle" names. * * @deprecated since 2.6, use core_component::normalize_component() * * @param string $component * @return array as (string)$type => (string)$plugin */ function normalize_component($component) { // NOTE: do not add any other debugging here, keep forever. return core_component::normalize_component($component); }
/** * Validates a submitted rating * * @param array $params submitted data * context => object the context in which the rated items exists [required] * component => The component the rating belongs to [required] * ratingarea => The ratingarea the rating is associated with [required] * itemid => int the ID of the object being rated [required] * scaleid => int the scale from which the user can select a rating. Used for bounds checking. [required] * rating => int the submitted rating * rateduserid => int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required] * aggregation => int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [optional] * @return boolean true if the rating is valid. False if callback wasnt found and will throw rating_exception if rating is invalid */ public function check_rating_is_valid($params) { if (!isset($params['context'])) { throw new coding_exception('The context option is a required option when checking rating validity.'); } if (!isset($params['component'])) { throw new coding_exception('The component option is now a required option when checking rating validity'); } if (!isset($params['ratingarea'])) { throw new coding_exception('The ratingarea option is now a required option when checking rating validity'); } if (!isset($params['itemid'])) { throw new coding_exception('The itemid option is now a required option when checking rating validity'); } if (!isset($params['scaleid'])) { throw new coding_exception('The scaleid option is now a required option when checking rating validity'); } if (!isset($params['rateduserid'])) { throw new coding_exception('The rateduserid option is now a required option when checking rating validity'); } list($plugintype, $pluginname) = core_component::normalize_component($params['component']); //this looks for a function like forum_rating_validate() in mod_forum lib.php //wrapping the params array in another array as call_user_func_array() expands arrays into multiple arguments $isvalid = plugin_callback($plugintype, $pluginname, 'rating', 'validate', array($params), null); //if null then the callback doesn't exist if ($isvalid === null) { $isvalid = false; debugging('rating validation callback not found for component ' . clean_param($component, PARAM_ALPHANUMEXT)); } return $isvalid; }
/** * Constructor. * @param string $component the component from version.php * @param string $expected expected directory, null means calculate * @param string $current plugin directory path */ public function __construct($component, $expected, $current) { global $CFG; if (empty($expected)) { list($type, $plugin) = core_component::normalize_component($component); $plugintypes = core_component::get_plugin_types(); if (isset($plugintypes[$type])) { $expected = $plugintypes[$type] . '/' . $plugin; } } if (strpos($expected, '$CFG->dirroot') !== 0) { $expected = str_replace($CFG->dirroot, '$CFG->dirroot', $expected); } if (strpos($current, '$CFG->dirroot') !== 0) { $current = str_replace($CFG->dirroot, '$CFG->dirroot', $current); } $a = new stdClass(); $a->component = $component; $a->expected = $expected; $a->current = $current; parent::__construct('detectedmisplacedplugin', 'core_plugin', "$CFG->wwwroot/$CFG->admin/index.php", $a); }
/** * Returns the list of gradable areas provided by the given component * * This performs a callback to the library of the relevant plugin to obtain * the list of supported areas. * * @param string $component normalized component name * @return array of (string)areacode => (string)localized title of the area */ public static function available_areas($component) { global $CFG; list($plugintype, $pluginname) = core_component::normalize_component($component); if ($component === 'core_grading') { return array(); } else { if ($plugintype === 'mod') { return plugin_callback('mod', $pluginname, 'grading', 'areas_list', null, array()); } else { throw new coding_exception('Unsupported area location'); } } }
/** * Determine if a component callback exists and return the function name to call. Note that this * function will include the required library files so that the functioname returned can be * called directly. * * @param string $component frankenstyle component name, e.g. 'mod_quiz' * @param string $function the rest of the function name, e.g. 'cron' will end up calling 'mod_quiz_cron' * @return mixed Complete function name to call if the callback exists or false if it doesn't. * @throws coding_exception if invalid component specfied */ function component_callback_exists($component, $function) { global $CFG; // This is needed for the inclusions. $cleancomponent = clean_param($component, PARAM_COMPONENT); if (empty($cleancomponent)) { throw new coding_exception('Invalid component used in plugin/component_callback():' . $component); } $component = $cleancomponent; list($type, $name) = core_component::normalize_component($component); $component = $type . '_' . $name; $oldfunction = $name . '_' . $function; $function = $component . '_' . $function; $dir = core_component::get_component_directory($component); if (empty($dir)) { throw new coding_exception('Invalid component used in plugin/component_callback():' . $component); } // Load library and look for function. if (file_exists($dir . '/lib.php')) { require_once $dir . '/lib.php'; } if (!function_exists($function) and function_exists($oldfunction)) { if ($type !== 'mod' and $type !== 'core') { debugging("Please use new function name {$function} instead of legacy {$oldfunction}", DEBUG_DEVELOPER); } $function = $oldfunction; } if (function_exists($function)) { return $function; } return false; }
/** * Normalize the component into the type and plugin name. * * @param $component * * @return array */ public function normalizeComponent($component) { $this->requireConfig(); /* @noinspection PhpUndefinedClassInspection */ return \core_component::normalize_component($component); }
/** * Perform the installation of plugins. * * If used for installation of remote plugins from the Moodle Plugins * directory, the $plugins must be list of {@link \core\update\remote_info} * object that represent installable remote plugins. The caller can use * {@link self::filter_installable()} to prepare the list. * * If used for installation of plugins from locally available ZIP files, * the $plugins should be list of objects with properties ->component and * ->zipfilepath. * * The method uses {@link mtrace()} to produce direct output and can be * used in both web and cli interfaces. * * @param array $plugins list of plugins * @param bool $confirmed should the files be really deployed into the dirroot? * @param bool $silent perform without output * @return bool true on success */ public function install_plugins(array $plugins, $confirmed, $silent) { global $CFG, $OUTPUT; if (!empty($CFG->disableupdateautodeploy)) { return false; } if (empty($plugins)) { return false; } $ok = get_string('ok', 'core'); // Let admins know they can expect more verbose output. $silent or $this->mtrace(get_string('packagesdebug', 'core_plugin'), PHP_EOL, DEBUG_NORMAL); // Download all ZIP packages if we do not have them yet. $zips = array(); foreach ($plugins as $plugin) { if ($plugin instanceof \core\update\remote_info) { $zips[$plugin->component] = $this->get_remote_plugin_zip($plugin->version->downloadurl, $plugin->version->downloadmd5); $silent or $this->mtrace(get_string('packagesdownloading', 'core_plugin', $plugin->component), ' ... '); $silent or $this->mtrace(PHP_EOL . ' <- ' . $plugin->version->downloadurl, '', DEBUG_DEVELOPER); $silent or $this->mtrace(PHP_EOL . ' -> ' . $zips[$plugin->component], ' ... ', DEBUG_DEVELOPER); if (!$zips[$plugin->component]) { $silent or $this->mtrace(get_string('error')); return false; } $silent or $this->mtrace($ok); } else { if (empty($plugin->zipfilepath)) { throw new coding_exception('Unexpected data structure provided'); } $zips[$plugin->component] = $plugin->zipfilepath; $silent or $this->mtrace('ZIP ' . $plugin->zipfilepath, PHP_EOL, DEBUG_DEVELOPER); } } // Validate all downloaded packages. foreach ($plugins as $plugin) { $zipfile = $zips[$plugin->component]; $silent or $this->mtrace(get_string('packagesvalidating', 'core_plugin', $plugin->component), ' ... '); list($plugintype, $pluginname) = core_component::normalize_component($plugin->component); $tmp = make_request_directory(); $zipcontents = $this->unzip_plugin_file($zipfile, $tmp, $pluginname); if (empty($zipcontents)) { $silent or $this->mtrace(get_string('error')); $silent or $this->mtrace('Unable to unzip ' . $zipfile, PHP_EOL, DEBUG_DEVELOPER); return false; } $validator = \core\update\validator::instance($tmp, $zipcontents); $validator->assert_plugin_type($plugintype); $validator->assert_moodle_version($CFG->version); // TODO Check for missing dependencies during validation. $result = $validator->execute(); if (!$silent) { $result ? $this->mtrace($ok) : $this->mtrace(get_string('error')); foreach ($validator->get_messages() as $message) { if ($message->level === $validator::INFO) { // Display [OK] validation messages only if debugging mode is DEBUG_NORMAL. $level = DEBUG_NORMAL; } else { if ($message->level === $validator::DEBUG) { // Display [Debug] validation messages only if debugging mode is DEBUG_ALL. $level = DEBUG_ALL; } else { // Display [Warning] and [Error] always. $level = null; } } if ($message->level === $validator::WARNING and !CLI_SCRIPT) { $this->mtrace(' <strong>[' . $validator->message_level_name($message->level) . ']</strong>', ' ', $level); } else { $this->mtrace(' [' . $validator->message_level_name($message->level) . ']', ' ', $level); } $this->mtrace($validator->message_code_name($message->msgcode), ' ', $level); $info = $validator->message_code_info($message->msgcode, $message->addinfo); if ($info) { $this->mtrace('[' . s($info) . ']', ' ', $level); } else { if (is_string($message->addinfo)) { $this->mtrace('[' . s($message->addinfo, true) . ']', ' ', $level); } else { $this->mtrace('[' . s(json_encode($message->addinfo, true)) . ']', ' ', $level); } } if ($icon = $validator->message_help_icon($message->msgcode)) { if (CLI_SCRIPT) { $this->mtrace(PHP_EOL . ' ^^^ ' . get_string('help') . ': ' . get_string($icon->identifier . '_help', $icon->component), '', $level); } else { $this->mtrace($OUTPUT->render($icon), ' ', $level); } } $this->mtrace(PHP_EOL, '', $level); } } if (!$result) { $silent or $this->mtrace(get_string('packagesvalidatingfailed', 'core_plugin')); return false; } } $silent or $this->mtrace(PHP_EOL . get_string('packagesvalidatingok', 'core_plugin')); if (!$confirmed) { return true; } // Extract all ZIP packs do the dirroot. foreach ($plugins as $plugin) { $silent or $this->mtrace(get_string('packagesextracting', 'core_plugin', $plugin->component), ' ... '); $zipfile = $zips[$plugin->component]; list($plugintype, $pluginname) = core_component::normalize_component($plugin->component); $target = $this->get_plugintype_root($plugintype); if (file_exists($target . '/' . $pluginname)) { $this->remove_plugin_folder($this->get_plugin_info($plugin->component)); } if (!$this->unzip_plugin_file($zipfile, $target, $pluginname)) { $silent or $this->mtrace(get_string('error')); $silent or $this->mtrace('Unable to unzip ' . $zipfile, PHP_EOL, DEBUG_DEVELOPER); if (function_exists('opcache_reset')) { opcache_reset(); } return false; } $silent or $this->mtrace($ok); } if (function_exists('opcache_reset')) { opcache_reset(); } return true; }
/** * Sets the component. * * This method shouldn't be public, changing the component once it has been set potentially * invalidates permission checks. * A coding_error is now thrown if code attempts to change the component. * * @param string $component */ public function set_component($component) { if (!empty($this->component) && $this->component !== $component) { throw new coding_exception('You cannot change the component of a comment once it has been set'); } $this->component = $component; list($this->plugintype, $this->pluginname) = core_component::normalize_component($component); }
/** * Returns the version of installed component * * @param string $component component name * @param string $source either 'disk' or 'installed' - where to get the version information from * @return string|bool version number or false if the component is not found */ function get_component_version($component, $source = 'installed') { global $CFG, $DB; list($type, $name) = core_component::normalize_component($component); // moodle core or a core subsystem if ($type === 'core') { if ($source === 'installed') { if (empty($CFG->version)) { return false; } else { return $CFG->version; } } else { if (!is_readable($CFG->dirroot . '/version.php')) { return false; } else { $version = null; //initialize variable for IDEs include $CFG->dirroot . '/version.php'; return $version; } } } // activity module if ($type === 'mod') { if ($source === 'installed') { if ($CFG->version < 2013092001.02) { return $DB->get_field('modules', 'version', array('name' => $name)); } else { return get_config('mod_' . $name, 'version'); } } else { $mods = core_component::get_plugin_list('mod'); if (empty($mods[$name]) or !is_readable($mods[$name] . '/version.php')) { return false; } else { $plugin = new stdClass(); $plugin->version = null; $module = $plugin; include $mods[$name] . '/version.php'; return $plugin->version; } } } // block if ($type === 'block') { if ($source === 'installed') { if ($CFG->version < 2013092001.02) { return $DB->get_field('block', 'version', array('name' => $name)); } else { return get_config('block_' . $name, 'version'); } } else { $blocks = core_component::get_plugin_list('block'); if (empty($blocks[$name]) or !is_readable($blocks[$name] . '/version.php')) { return false; } else { $plugin = new stdclass(); include $blocks[$name] . '/version.php'; return $plugin->version; } } } // all other plugin types if ($source === 'installed') { return get_config($type . '_' . $name, 'version'); } else { $plugins = core_component::get_plugin_list($type); if (empty($plugins[$name])) { return false; } else { $plugin = new stdclass(); include $plugins[$name] . '/version.php'; return $plugin->version; } } }
/** * Gather a list of dndupload handlers from the different mods * * @param object $course The course this is being added to (to check course_allowed_module() ) */ public function __construct($course, $modnames = null) { global $CFG, $PAGE; // Add some default types to handle. // Note: 'Files' type is hard-coded into the Javascript as this needs to be ... // ... treated a little differently. $this->register_type('url', array('url', 'text/uri-list', 'text/x-moz-url'), get_string('addlinkhere', 'moodle'), get_string('nameforlink', 'moodle'), get_string('whatforlink', 'moodle'), 10); $this->register_type('text/html', array('text/html'), get_string('addpagehere', 'moodle'), get_string('nameforpage', 'moodle'), get_string('whatforpage', 'moodle'), 20); $this->register_type('text', array('text', 'text/plain'), get_string('addpagehere', 'moodle'), get_string('nameforpage', 'moodle'), get_string('whatforpage', 'moodle'), 30); // Loop through all modules to find handlers. $mods = get_plugin_list_with_function('mod', 'dndupload_register'); foreach ($mods as $component => $funcname) { list($modtype, $modname) = core_component::normalize_component($component); if ($modnames && !array_key_exists($modname, $modnames)) { continue; // Module is deactivated (hidden) at the site level. } if (!course_allowed_module($course, $modname)) { continue; // User does not have permission to add this module to the course. } $resp = $funcname(); if (!$resp) { continue; } if (isset($resp['files'])) { foreach ($resp['files'] as $file) { $this->register_file_handler($file['extension'], $modname, $file['message']); } } if (isset($resp['addtypes'])) { foreach ($resp['addtypes'] as $type) { if (isset($type['priority'])) { $priority = $type['priority']; } else { $priority = 100; } if (!isset($type['handlermessage'])) { $type['handlermessage'] = ''; } $this->register_type($type['identifier'], $type['datatransfertypes'], $type['addmessage'], $type['namemessage'], $type['handlermessage'], $priority); } } if (isset($resp['types'])) { foreach ($resp['types'] as $type) { $noname = !empty($type['noname']); $this->register_type_handler($type['identifier'], $modname, $type['message'], $noname); } } $PAGE->requires->string_for_js('pluginname', $modname); } }
/** * This test is a built-in validation of deprecated.txt files in lang locations. * * It will fail if the string in the wrong format or non-existing (mistyped) string was deprecated. */ public function test_validate_deprecated_strings_files() { global $CFG; $stringman = get_string_manager(); $teststringman = testable_core_string_manager::instance($CFG->langotherroot, $CFG->langlocalroot, array()); $allstrings = $teststringman->get_all_deprecated_strings(); foreach ($allstrings as $string) { if (!preg_match('/^(.*),(.*)$/', $string, $matches) || clean_param($matches[2], PARAM_COMPONENT) !== $matches[2]) { $this->fail('String "' . $string . '" appearing in one of the lang/en/deprecated.txt files does not have correct syntax'); } list($pluginttype, $pluginname) = core_component::normalize_component($matches[2]); if ($matches[2] !== $pluginttype . '_' . $pluginname) { $this->fail('String "' . $string . '" appearing in one of the lang/en/deprecated.txt files does not have normalised component name'); } if (!$stringman->string_exists($matches[1], $matches[2])) { $this->fail('String "' . $string . '" appearing in one of the lang/en/deprecated.txt files does not exist'); } } }
/** * Writes strings into a local language pack file * * @param string $component the name of the component * @param array $strings */ protected static function dump_strings($lang, $component, $strings) { global $CFG; if ($lang !== clean_param($lang, PARAM_LANG)) { debugging('Unable to dump local strings for non-installed language pack .' . s($lang)); return false; } if ($component !== clean_param($component, PARAM_COMPONENT)) { throw new coding_exception('Incorrect component name'); } if (!($filename = self::get_component_filename($component))) { debugging('Unable to find the filename for the component ' . s($component)); return false; } if ($filename !== clean_param($filename, PARAM_FILE)) { throw new coding_exception('Incorrect file name ' . s($filename)); } list($package, $subpackage) = core_component::normalize_component($component); $packageinfo = " * @package {$package}"; if (!is_null($subpackage)) { $packageinfo .= "\n * @subpackage {$subpackage}"; } $filepath = self::get_localpack_location($lang); $filepath = $filepath . '/' . $filename; if (!is_dir(dirname($filepath))) { check_dir_exists(dirname($filepath)); } if (!($f = fopen($filepath, 'w'))) { debugging('Unable to write ' . s($filepath)); return false; } fwrite($f, <<<EOF <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Local language pack from {$CFG->wwwroot} * {$packageinfo} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); EOF ); foreach ($strings as $stringid => $text) { if ($stringid !== clean_param($stringid, PARAM_STRINGID)) { debugging('Invalid string identifier ' . s($stringid)); continue; } fwrite($f, '$string[\'' . $stringid . '\'] = '); fwrite($f, var_export($text, true)); fwrite($f, ";\n"); } fclose($f); @chmod($filepath, $CFG->filepermissions); }