Ejemplo n.º 1
0
 /**
  * Load handler instances for all of the handlers defined in db/messageinbound_handlers.php for the specified component.
  *
  * @param string $componentname - The name of the component to fetch the handlers for.
  * @return \core\message\inbound\handler[] - List of handlers for this component.
  */
 public static function load_default_handlers_for_component($componentname)
 {
     $componentname = \core_component::normalize_componentname($componentname);
     $dir = \core_component::get_component_directory($componentname);
     if (!$dir) {
         return array();
     }
     $file = $dir . '/db/messageinbound_handlers.php';
     if (!file_exists($file)) {
         return array();
     }
     $handlers = null;
     require_once $file;
     if (!isset($handlers)) {
         return array();
     }
     $handlerinstances = array();
     foreach ($handlers as $handler) {
         $record = (object) $handler;
         $record->component = $componentname;
         if ($handlerinstance = self::handler_from_record($record)) {
             $handlerinstances[] = $handlerinstance;
         } else {
             throw new \coding_exception("Inbound Message Handler not found for '{$componentname}'.");
         }
     }
     return $handlerinstances;
 }
Ejemplo n.º 2
0
 /**
  * Given a component name, will load the list of tasks in the db/tasks.php file for that component.
  *
  * @param string $componentname - The name of the component to fetch the tasks for.
  * @return \core\task\scheduled_task[] - List of scheduled tasks for this component.
  */
 public static function load_default_scheduled_tasks_for_component($componentname)
 {
     $dir = \core_component::get_component_directory($componentname);
     if (!$dir) {
         return array();
     }
     $file = $dir . '/' . CORE_TASK_TASKS_FILENAME;
     if (!file_exists($file)) {
         return array();
     }
     $tasks = null;
     include $file;
     if (!isset($tasks)) {
         return array();
     }
     $scheduledtasks = array();
     foreach ($tasks as $task) {
         $record = (object) $task;
         $scheduledtask = self::scheduled_task_from_record($record);
         // Safety check in case the task in the DB does not match a real class (maybe something was uninstalled).
         if ($scheduledtask) {
             $scheduledtask->set_component($componentname);
             $scheduledtasks[] = $scheduledtask;
         }
     }
     return $scheduledtasks;
 }
Ejemplo n.º 3
0
/**
 * Returns detailed function information
 *
 * @param string|object $function name of external function or record from external_function
 * @param int $strictness IGNORE_MISSING means compatible mode, false returned if record not found, debug message if more found;
 *                        MUST_EXIST means throw exception if no record or multiple records found
 * @return stdClass description or false if not found or exception thrown
 * @since Moodle 2.0
 */
function external_function_info($function, $strictness = MUST_EXIST)
{
    global $DB, $CFG;
    if (!is_object($function)) {
        if (!($function = $DB->get_record('external_functions', array('name' => $function), '*', $strictness))) {
            return false;
        }
    }
    //first find and include the ext implementation class
    $function->classpath = empty($function->classpath) ? core_component::get_component_directory($function->component) . '/externallib.php' : $CFG->dirroot . '/' . $function->classpath;
    if (!file_exists($function->classpath)) {
        throw new coding_exception('Can not find file with external function implementation');
    }
    require_once $function->classpath;
    $function->parameters_method = $function->methodname . '_parameters';
    $function->returns_method = $function->methodname . '_returns';
    // make sure the implementaion class is ok
    if (!method_exists($function->classname, $function->methodname)) {
        throw new coding_exception('Missing implementation method of ' . $function->classname . '::' . $function->methodname);
    }
    if (!method_exists($function->classname, $function->parameters_method)) {
        throw new coding_exception('Missing parameters description');
    }
    if (!method_exists($function->classname, $function->returns_method)) {
        throw new coding_exception('Missing returned values description');
    }
    // fetch the parameters description
    $function->parameters_desc = call_user_func(array($function->classname, $function->parameters_method));
    if (!$function->parameters_desc instanceof external_function_parameters) {
        throw new coding_exception('Invalid parameters description');
    }
    // fetch the return values description
    $function->returns_desc = call_user_func(array($function->classname, $function->returns_method));
    // null means void result or result is ignored
    if (!is_null($function->returns_desc) and !$function->returns_desc instanceof external_description) {
        throw new coding_exception('Invalid return description');
    }
    //now get the function description
    //TODO MDL-31115 use localised lang pack descriptions, it would be nice to have
    //      easy to understand descriptions in admin UI,
    //      on the other hand this is still a bit in a flux and we need to find some new naming
    //      conventions for these descriptions in lang packs
    $function->description = null;
    $servicesfile = core_component::get_component_directory($function->component) . '/db/services.php';
    if (file_exists($servicesfile)) {
        $functions = null;
        include $servicesfile;
        if (isset($functions[$function->name]['description'])) {
            $function->description = $functions[$function->name]['description'];
        }
        if (isset($functions[$function->name]['testclientpath'])) {
            $function->testclientpath = $functions[$function->name]['testclientpath'];
        }
    }
    return $function;
}
Ejemplo n.º 4
0
/**
 * Loads the events definitions for the component (from file). If no
 * events are defined for the component, we simply return an empty array.
 *
 * @access protected To be used from eventslib only
 *
 * @param string $component examples: 'moodle', 'mod_forum', 'block_quiz_results'
 * @return array Array of capabilities or empty array if not exists
 */
function events_load_def($component)
{
    global $CFG;
    if ($component === 'unittest') {
        $defpath = $CFG->dirroot . '/lib/tests/fixtures/events.php';
    } else {
        $defpath = core_component::get_component_directory($component) . '/db/events.php';
    }
    $handlers = array();
    if (file_exists($defpath)) {
        require $defpath;
    }
    // make sure the definitions are valid and complete; tell devs what is wrong
    foreach ($handlers as $eventname => $handler) {
        if ($eventname === 'reset') {
            debugging("'reset' can not be used as event name.");
            unset($handlers['reset']);
            continue;
        }
        if (!is_array($handler)) {
            debugging("Handler of '{$eventname}' must be specified as array'");
            unset($handlers[$eventname]);
            continue;
        }
        if (!isset($handler['handlerfile'])) {
            debugging("Handler of '{$eventname}' must include 'handlerfile' key'");
            unset($handlers[$eventname]);
            continue;
        }
        if (!isset($handler['handlerfunction'])) {
            debugging("Handler of '{$eventname}' must include 'handlerfunction' key'");
            unset($handlers[$eventname]);
            continue;
        }
        if (!isset($handler['schedule'])) {
            $handler['schedule'] = 'instant';
        }
        if ($handler['schedule'] !== 'instant' and $handler['schedule'] !== 'cron') {
            debugging("Handler of '{$eventname}' must include valid 'schedule' type (instant or cron)'");
            unset($handlers[$eventname]);
            continue;
        }
        if (!isset($handler['internal'])) {
            $handler['internal'] = 1;
        }
        $handlers[$eventname] = $handler;
    }
    return $handlers;
}
Ejemplo n.º 5
0
 /**
  * Test requirejs loader
  */
 public function test_requirejs()
 {
     global $CFG;
     // Find a core module.
     $result = core_requirejs::find_one_amd_module('core', 'templates', false);
     $expected = ['core/templates' => $CFG->dirroot . '/lib/amd/build/templates.min.js'];
     $this->assertEquals($expected, $result);
     $result = core_requirejs::find_one_amd_module('core', 'templates', true);
     $expected = ['core/templates' => $CFG->dirroot . '/lib/amd/src/templates.js'];
     $this->assertEquals($expected, $result);
     // Find a subsystem module (none exist yet).
     $result = core_requirejs::find_one_amd_module('core_group', 'doesnotexist', false);
     $expected = [];
     $this->assertEquals($expected, $result);
     // Find a plugin module.
     $result = core_requirejs::find_one_amd_module('mod_assign', 'grading_panel', true);
     $expected = ['mod_assign/grading_panel' => $CFG->dirroot . '/mod/assign/amd/src/grading_panel.js'];
     $this->assertEquals($expected, $result);
     // Find all modules - no debugging.
     $result = core_requirejs::find_all_amd_modules(true);
     foreach ($result as $key => $path) {
         // Lets verify the first part of the key is a valid component name and the second part correctly contains "min" or not.
         list($component, $template) = explode('/', $key, 2);
         // Can we resolve it to a valid dir?
         $dir = core_component::get_component_directory($component);
         $this->assertNotEmpty($dir);
         // Only "core" is allowed to have no _ in component names.
         if (strpos($component, '_') === false) {
             $this->assertEquals('core', $component);
         }
         $this->assertNotContains('.min', $path);
     }
     // Find all modules - debugging.
     $result = core_requirejs::find_all_amd_modules(false);
     foreach ($result as $key => $path) {
         // Lets verify the first part of the key is a valid component name and the second part correctly contains "min" or not.
         list($component, $template) = explode('/', $key, 2);
         $dir = core_component::get_component_directory($component);
         $this->assertNotEmpty($dir);
         // Only "core" is allowed to have no _ in component names.
         if (strpos($component, '_') === false) {
             $this->assertEquals('core', $component);
         }
         $this->assertContains('.min', $path);
     }
 }
Ejemplo n.º 6
0
 /**
  * Validate data.
  *
  * This ensures that:
  * - Plugins are only used once,
  * - Group names are unique,
  * - Lines match: group = plugin[, plugin[, plugin ...]],
  * - There are some groups and plugins defined,
  * - The plugins used are installed.
  *
  * @param string $data
  * @return mixed True on success, else error message.
  */
 public function validate($data)
 {
     $result = parent::validate($data);
     if ($result !== true) {
         return $result;
     }
     $lines = explode("\n", $data);
     $groups = array();
     $plugins = array();
     foreach ($lines as $line) {
         if (!trim($line)) {
             continue;
         }
         $matches = array();
         if (!preg_match('/^\\s*([a-z0-9]+)\\s*=\\s*([a-z0-9]+(\\s*,\\s*[a-z0-9]+)*)+\\s*$/', $line, $matches)) {
             $result = get_string('errorcannotparseline', 'editor_atto', $line);
             break;
         }
         $group = $matches[1];
         if (isset($groups[$group])) {
             $result = get_string('errorgroupisusedtwice', 'editor_atto', $group);
             break;
         }
         $groups[$group] = true;
         $lineplugins = array_map('trim', explode(',', $matches[2]));
         foreach ($lineplugins as $plugin) {
             if (isset($plugins[$plugin])) {
                 $result = get_string('errorpluginisusedtwice', 'editor_atto', $plugin);
                 break 2;
             } else {
                 if (!core_component::get_component_directory('atto_' . $plugin)) {
                     $result = get_string('errorpluginnotfound', 'editor_atto', $plugin);
                     break 2;
                 }
             }
             $plugins[$plugin] = true;
         }
     }
     // We did not find any groups or plugins.
     if (empty($groups) || empty($plugins)) {
         $result = get_string('errornopluginsorgroupsfound', 'editor_atto');
     }
     return $result;
 }
Ejemplo n.º 7
0
 /**
  * Check a single module exists and return the full path to it.
  *
  * The expected location for amd modules is:
  *  <componentdir>/amd/src/modulename.js
  *
  * @param string $component The component determines the folder the js file should be in.
  * @param string $jsfilename The filename for the module (with the js extension).
  * @param boolean $debug If true, returns the paths to the original (unminified) source files.
  * @return array $files An array of mappings from module names to file paths.
  *                      Empty array if the file does not exist.
  */
 public static function find_one_amd_module($component, $jsfilename, $debug = false)
 {
     $jsfileroot = core_component::get_component_directory($component);
     if (!$jsfileroot) {
         return array();
     }
     $module = str_replace('.js', '', $jsfilename);
     $srcdir = $jsfileroot . '/amd/build';
     $minpart = '.min';
     if ($debug) {
         $srcdir = $jsfileroot . '/amd/src';
         $minpart = '';
     }
     $filename = $srcdir . '/' . $module . $minpart . '.js';
     if (!file_exists($filename)) {
         return array();
     }
     $fullmodulename = $component . '/' . $module;
     return array($fullmodulename => $filename);
 }
Ejemplo n.º 8
0
 /**
  * Given a component name, will load the list of tasks in the db/tasks.php file for that component.
  *
  * @param string $componentname - The name of the component to fetch the tasks for.
  * @return \core\task\scheduled_task[] - List of scheduled tasks for this component.
  */
 public static function load_default_scheduled_tasks_for_component($componentname)
 {
     $dir = \core_component::get_component_directory($componentname);
     if (!$dir) {
         return array();
     }
     $file = $dir . '/' . CORE_TASK_TASKS_FILENAME;
     if (!file_exists($file)) {
         return array();
     }
     $tasks = null;
     require_once $file;
     if (!isset($tasks)) {
         return array();
     }
     $scheduledtasks = array();
     foreach ($tasks as $task) {
         $record = (object) $task;
         $scheduledtask = self::scheduled_task_from_record($record);
         $scheduledtask->set_component($componentname);
         $scheduledtasks[] = $scheduledtask;
     }
     return $scheduledtasks;
 }
Ejemplo n.º 9
0
/**
 * 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
    }
}
Ejemplo n.º 10
0
 /**
  * Return user information including profile picture + basic site information
  * Note:
  * - no capability checking because we return only known information about logged user
  *
  * @param array $serviceshortnames - DEPRECATED PARAMETER - values will be ignored -
  * it was an original design error, we keep for backward compatibility.
  * @return array site info
  * @since Moodle 2.2
  */
 public static function get_site_info($serviceshortnames = array())
 {
     global $USER, $SITE, $CFG, $DB;
     $params = self::validate_parameters(self::get_site_info_parameters(), array('serviceshortnames' => $serviceshortnames));
     $context = context_user::instance($USER->id);
     $profileimageurl = moodle_url::make_pluginfile_url($context->id, 'user', 'icon', null, '/', 'f1');
     // Site information.
     $siteinfo = array('sitename' => $SITE->fullname, 'siteurl' => $CFG->wwwroot, 'username' => $USER->username, 'firstname' => $USER->firstname, 'lastname' => $USER->lastname, 'fullname' => fullname($USER), 'lang' => current_language(), 'userid' => $USER->id, 'userpictureurl' => $profileimageurl->out(false));
     // Retrieve the service and functions from the web service linked to the token
     // If you call this function directly from external (not a web service call),
     // then it will still return site info without information about a service
     // Note: wsusername/wspassword ws authentication is not supported.
     $functions = array();
     if ($CFG->enablewebservices) {
         // No need to check token if web service are disabled and not a ws call.
         $token = optional_param('wstoken', '', PARAM_ALPHANUM);
         if (!empty($token)) {
             // No need to run if not a ws call.
             // Retrieve service shortname.
             $servicesql = 'SELECT s.*
                            FROM {external_services} s, {external_tokens} t
                            WHERE t.externalserviceid = s.id AND token = ? AND t.userid = ? AND s.enabled = 1';
             $service = $DB->get_record_sql($servicesql, array($token, $USER->id));
             $siteinfo['downloadfiles'] = $service->downloadfiles;
             $siteinfo['uploadfiles'] = $service->uploadfiles;
             if (!empty($service)) {
                 // Return the release and version number for web service users only.
                 $siteinfo['release'] = $CFG->release;
                 $siteinfo['version'] = $CFG->version;
                 // Retrieve the functions.
                 $functionssql = "SELECT f.*\n                            FROM {external_functions} f, {external_services_functions} sf\n                            WHERE f.name = sf.functionname AND sf.externalserviceid = ?";
                 $functions = $DB->get_records_sql($functionssql, array($service->id));
             } else {
                 throw new coding_exception('No service found in get_site_info: something is buggy, \\
                                             it should have fail at the ws server authentication layer.');
             }
         }
     }
     // Build up the returned values of the list of functions.
     $componentversions = array();
     $availablefunctions = array();
     foreach ($functions as $function) {
         $functioninfo = array();
         $functioninfo['name'] = $function->name;
         if ($function->component == 'moodle' || $function->component == 'core') {
             $version = $CFG->version;
             // Moodle version.
         } else {
             $versionpath = core_component::get_component_directory($function->component) . '/version.php';
             if (is_readable($versionpath)) {
                 // We store the component version once retrieved (so we don't load twice the version.php).
                 if (!isset($componentversions[$function->component])) {
                     $plugin = new stdClass();
                     include $versionpath;
                     $componentversions[$function->component] = $plugin->version;
                     $version = $plugin->version;
                 } else {
                     $version = $componentversions[$function->component];
                 }
             } else {
                 // Function component should always have a version.php,
                 // otherwise the function should have been described with component => 'moodle'.
                 throw new moodle_exception('missingversionfile', 'webservice', '', $function->component);
             }
         }
         $functioninfo['version'] = $version;
         $availablefunctions[] = $functioninfo;
     }
     $siteinfo['functions'] = $availablefunctions;
     // Mobile CSS theme and alternative login url.
     $siteinfo['mobilecssurl'] = $CFG->mobilecssurl;
     // Retrieve some advanced features. Only enable/disable ones (bool).
     $advancedfeatures = array("usecomments", "usetags", "enablenotes", "messaging", "enableblogs", "enablecompletion", "enablebadges");
     foreach ($advancedfeatures as $feature) {
         if (isset($CFG->{$feature})) {
             $siteinfo['advancedfeatures'][] = array('name' => $feature, 'value' => (int) $CFG->{$feature});
         }
     }
     // Special case mnet_dispatcher_mode.
     $siteinfo['advancedfeatures'][] = array('name' => 'mnet_dispatcher_mode', 'value' => $CFG->mnet_dispatcher_mode == 'strict' ? 1 : 0);
     // User can manage own files.
     $siteinfo['usercanmanageownfiles'] = has_capability('moodle/user:manageownfiles', $context);
     // User quota. 0 means user can ignore the quota.
     $siteinfo['userquota'] = 0;
     if (!has_capability('moodle/user:ignoreuserquota', $context)) {
         $siteinfo['userquota'] = $CFG->userquota;
     }
     // User max upload file size. -1 means the user can ignore the upload file size.
     $siteinfo['usermaxuploadfilesize'] = get_user_max_upload_file_size($context, $CFG->maxbytes);
     return $siteinfo;
 }
Ejemplo n.º 11
0
/**
 * Called by pluginfile.php to serve files related to the 'question' core
 * component and for files belonging to qtypes.
 *
 * For files that relate to questions in a question_attempt, then we delegate to
 * a function in the component that owns the attempt (for example in the quiz,
 * or in core question preview) to get necessary inforation.
 *
 * (Note that, at the moment, all question file areas relate to questions in
 * attempts, so the If at the start of the last paragraph is always true.)
 *
 * Does not return, either calls send_file_not_found(); or serves the file.
 *
 * @package  core_question
 * @category files
 * @param stdClass $course course settings object
 * @param stdClass $context context object
 * @param string $component the name of the component we are serving files for.
 * @param string $filearea the name of the file area.
 * @param array $args the remaining bits of the file path.
 * @param bool $forcedownload whether the user must be forced to download the file.
 * @param array $options additional options affecting the file serving
 */
function question_pluginfile($course, $context, $component, $filearea, $args, $forcedownload, array $options = array())
{
    global $DB, $CFG;
    // Special case, sending a question bank export.
    if ($filearea === 'export') {
        list($context, $course, $cm) = get_context_info_array($context->id);
        require_login($course, false, $cm);
        require_once $CFG->dirroot . '/question/editlib.php';
        $contexts = new question_edit_contexts($context);
        // check export capability
        $contexts->require_one_edit_tab_cap('export');
        $category_id = (int) array_shift($args);
        $format = array_shift($args);
        $cattofile = array_shift($args);
        $contexttofile = array_shift($args);
        $filename = array_shift($args);
        // load parent class for import/export
        require_once $CFG->dirroot . '/question/format.php';
        require_once $CFG->dirroot . '/question/editlib.php';
        require_once $CFG->dirroot . '/question/format/' . $format . '/format.php';
        $classname = 'qformat_' . $format;
        if (!class_exists($classname)) {
            send_file_not_found();
        }
        $qformat = new $classname();
        if (!($category = $DB->get_record('question_categories', array('id' => $category_id)))) {
            send_file_not_found();
        }
        $qformat->setCategory($category);
        $qformat->setContexts($contexts->having_one_edit_tab_cap('export'));
        $qformat->setCourse($course);
        if ($cattofile == 'withcategories') {
            $qformat->setCattofile(true);
        } else {
            $qformat->setCattofile(false);
        }
        if ($contexttofile == 'withcontexts') {
            $qformat->setContexttofile(true);
        } else {
            $qformat->setContexttofile(false);
        }
        if (!$qformat->exportpreprocess()) {
            send_file_not_found();
            print_error('exporterror', 'question', $thispageurl->out());
        }
        // export data to moodle file pool
        if (!($content = $qformat->exportprocess(true))) {
            send_file_not_found();
        }
        send_file($content, $filename, 0, 0, true, true, $qformat->mime_type());
    }
    // Normal case, a file belonging to a question.
    $qubaidorpreview = array_shift($args);
    // Two sub-cases: 1. A question being previewed outside an attempt/usage.
    if ($qubaidorpreview === 'preview') {
        $previewcontextid = (int) array_shift($args);
        $previewcomponent = array_shift($args);
        $questionid = (int) array_shift($args);
        $previewcontext = context_helper::instance_by_id($previewcontextid);
        $result = component_callback($previewcomponent, 'question_preview_pluginfile', array($previewcontext, $questionid, $context, $component, $filearea, $args, $forcedownload, $options), 'newcallbackmissing');
        if ($result === 'newcallbackmissing' && ($filearea = 'questiontext')) {
            // Fall back to the legacy callback for backwards compatibility.
            debugging("Component {$previewcomponent} does not define the expected " . "{$previewcomponent}_question_preview_pluginfile callback. Falling back to the deprecated " . "{$previewcomponent}_questiontext_preview_pluginfile callback.", DEBUG_DEVELOPER);
            component_callback($previewcomponent, 'questiontext_preview_pluginfile', array($previewcontext, $questionid, $args, $forcedownload, $options));
        }
        send_file_not_found();
    }
    // 2. A question being attempted in the normal way.
    $qubaid = (int) $qubaidorpreview;
    $slot = (int) array_shift($args);
    $module = $DB->get_field('question_usages', 'component', array('id' => $qubaid));
    if ($module === 'core_question_preview') {
        require_once $CFG->dirroot . '/question/previewlib.php';
        return question_preview_question_pluginfile($course, $context, $component, $filearea, $qubaid, $slot, $args, $forcedownload, $options);
    } else {
        $dir = core_component::get_component_directory($module);
        if (!file_exists("{$dir}/lib.php")) {
            send_file_not_found();
        }
        include_once "{$dir}/lib.php";
        $filefunction = $module . '_question_pluginfile';
        if (function_exists($filefunction)) {
            $filefunction($course, $context, $component, $filearea, $qubaid, $slot, $args, $forcedownload, $options);
        }
        // Okay, we're here so lets check for function without 'mod_'.
        if (strpos($module, 'mod_') === 0) {
            $filefunctionold = substr($module, 4) . '_question_pluginfile';
            if (function_exists($filefunctionold)) {
                $filefunctionold($course, $context, $component, $filearea, $qubaid, $slot, $args, $forcedownload, $options);
            }
        }
        send_file_not_found();
    }
}
Ejemplo n.º 12
0
 /**
  * Assign roles
  *
  * This has to be called after enrolments processing.
  *
  * @param mixed $data
  * @return void
  */
 public function process_assignment($data)
 {
     global $DB;
     $data = (object) $data;
     // Check roleid, userid are one of the mapped ones
     if (!($newroleid = $this->get_mappingid('role', $data->roleid))) {
         return;
     }
     if (!($newuserid = $this->get_mappingid('user', $data->userid))) {
         return;
     }
     if (!$DB->record_exists('user', array('id' => $newuserid, 'deleted' => 0))) {
         // Only assign roles to not deleted users
         return;
     }
     if (!($contextid = $this->task->get_contextid())) {
         return;
     }
     if (empty($data->component)) {
         // assign standard manual roles
         // TODO: role_assign() needs one userid param to be able to specify our restore userid
         role_assign($newroleid, $newuserid, $contextid);
     } else {
         if (strpos($data->component, 'enrol_') === 0) {
             // Deal with enrolment roles - ignore the component and just find out the instance via new id,
             // it is possible that enrolment was restored using different plugin type.
             if (!isset($this->plugins)) {
                 $this->plugins = enrol_get_plugins(true);
             }
             if ($enrolid = $this->get_mappingid('enrol', $data->itemid)) {
                 if ($instance = $DB->get_record('enrol', array('id' => $enrolid))) {
                     if (isset($this->plugins[$instance->enrol])) {
                         $this->plugins[$instance->enrol]->restore_role_assignment($instance, $newroleid, $newuserid, $contextid);
                     }
                 }
             }
         } else {
             $data->roleid = $newroleid;
             $data->userid = $newuserid;
             $data->contextid = $contextid;
             $dir = core_component::get_component_directory($data->component);
             if ($dir and is_dir($dir)) {
                 if (component_callback($data->component, 'restore_role_assignment', array($this, $data), true)) {
                     return;
                 }
             }
             // Bad luck, plugin could not restore the data, let's add normal membership.
             role_assign($data->roleid, $data->userid, $data->contextid);
             $message = "Restore of '{$data->component}/{$data->itemid}' role assignments is not supported, using manual role assignments instead.";
             $this->log($message, backup::LOG_WARNING);
         }
     }
 }
Ejemplo n.º 13
0
    }
    if ($version === 'moodle') {
        if (count($bits) <= 3) {
            // This is an invalid module load attempt.
            $content .= "\n// Incorrect moodle module inclusion. Not enough component information in {$part}.\n";
            continue;
        }
        $revision = (int)array_shift($bits);
        if ($revision === -1) {
            // Revision -1 says please don't cache the JS
            $cache = false;
        }
        $frankenstyle = array_shift($bits);
        $filename = array_pop($bits);
        $modulename = $bits[0];
        $dir = core_component::get_component_directory($frankenstyle);

        // For shifted YUI modules, we need the YUI module name in frankenstyle format.
        $frankenstylemodulename = join('-', array($version, $frankenstyle, $modulename));
        $frankenstylefilename = preg_replace('/' . $modulename . '/', $frankenstylemodulename, $filename);

        // Submodules are stored in a directory with the full submodule name.
        // We need to remove the -debug.js, -min.js, and .js from the file name to calculate that directory name.
        $frankenstyledirectoryname = str_replace(array('-min.js', '-debug.js', '.js', '.css'), '', $frankenstylefilename);

        // By default, try and use the /yui/build directory.
        $contentfile = $dir . '/yui/build/' . $frankenstyledirectoryname;
        if ($mimetype == 'text/css') {
            // CSS assets are in a slightly different place to the JS.
            $contentfile = $contentfile . '/assets/skins/sam/' . $frankenstylefilename;
Ejemplo n.º 14
0
/**
 * Loads the messages definitions for a component from file
 *
 * If no messages are defined for the component, return an empty array.
 * This is an internal function used within messagelib.php
 *
 * @see message_update_providers()
 * @see message_update_processors()
 * @param string $component A moodle component like 'moodle', 'mod_forum', 'block_quiz_results'
 * @return array An array of message providers or empty array if not exists
 */
function message_get_providers_from_file($component) {
    $defpath = core_component::get_component_directory($component).'/db/messages.php';

    $messageproviders = array();

    if (file_exists($defpath)) {
        require($defpath);
    }

    foreach ($messageproviders as $name => $messageprovider) {   // Fix up missing values if required
        if (empty($messageprovider['capability'])) {
            $messageproviders[$name]['capability'] = NULL;
        }
        if (empty($messageprovider['defaults'])) {
            $messageproviders[$name]['defaults'] = array();
        }
    }

    return $messageproviders;
}
Ejemplo n.º 15
0
/**
 * This function delegates file serving to individual plugins
 *
 * @param string $relativepath
 * @param bool $forcedownload
 * @param null|string $preview the preview mode, defaults to serving the original file
 * @todo MDL-31088 file serving improments
 */
function file_pluginfile($relativepath, $forcedownload, $preview = null)
{
    global $DB, $CFG, $USER;
    // relative path must start with '/'
    if (!$relativepath) {
        print_error('invalidargorconf');
    } else {
        if ($relativepath[0] != '/') {
            print_error('pathdoesnotstartslash');
        }
    }
    // extract relative path components
    $args = explode('/', ltrim($relativepath, '/'));
    if (count($args) < 3) {
        // always at least context, component and filearea
        print_error('invalidarguments');
    }
    $contextid = (int) array_shift($args);
    $component = clean_param(array_shift($args), PARAM_COMPONENT);
    $filearea = clean_param(array_shift($args), PARAM_AREA);
    list($context, $course, $cm) = get_context_info_array($contextid);
    $fs = get_file_storage();
    // ========================================================================================================================
    if ($component === 'blog') {
        // Blog file serving
        if ($context->contextlevel != CONTEXT_SYSTEM) {
            send_file_not_found();
        }
        if ($filearea !== 'attachment' and $filearea !== 'post') {
            send_file_not_found();
        }
        if (empty($CFG->enableblogs)) {
            print_error('siteblogdisable', 'blog');
        }
        $entryid = (int) array_shift($args);
        if (!($entry = $DB->get_record('post', array('module' => 'blog', 'id' => $entryid)))) {
            send_file_not_found();
        }
        if ($CFG->bloglevel < BLOG_GLOBAL_LEVEL) {
            require_login();
            if (isguestuser()) {
                print_error('noguest');
            }
            if ($CFG->bloglevel == BLOG_USER_LEVEL) {
                if ($USER->id != $entry->userid) {
                    send_file_not_found();
                }
            }
        }
        if ($entry->publishstate === 'public') {
            if ($CFG->forcelogin) {
                require_login();
            }
        } else {
            if ($entry->publishstate === 'site') {
                require_login();
                //ok
            } else {
                if ($entry->publishstate === 'draft') {
                    require_login();
                    if ($USER->id != $entry->userid) {
                        send_file_not_found();
                    }
                }
            }
        }
        $filename = array_pop($args);
        $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
        if (!($file = $fs->get_file($context->id, $component, $filearea, $entryid, $filepath, $filename)) or $file->is_directory()) {
            send_file_not_found();
        }
        send_stored_file($file, 10 * 60, 0, true, array('preview' => $preview));
        // download MUST be forced - security!
        // ========================================================================================================================
    } else {
        if ($component === 'grade') {
            if (($filearea === 'outcome' or $filearea === 'scale') and $context->contextlevel == CONTEXT_SYSTEM) {
                // Global gradebook files
                if ($CFG->forcelogin) {
                    require_login();
                }
                $fullpath = "/{$context->id}/{$component}/{$filearea}/" . implode('/', $args);
                if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) {
                    send_file_not_found();
                }
                \core\session\manager::write_close();
                // Unlock session during file serving.
                send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview));
            } else {
                if ($filearea === 'feedback' and $context->contextlevel == CONTEXT_COURSE) {
                    //TODO: nobody implemented this yet in grade edit form!!
                    send_file_not_found();
                    if ($CFG->forcelogin || $course->id != SITEID) {
                        require_login($course);
                    }
                    $fullpath = "/{$context->id}/{$component}/{$filearea}/" . implode('/', $args);
                    if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) {
                        send_file_not_found();
                    }
                    \core\session\manager::write_close();
                    // Unlock session during file serving.
                    send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview));
                } else {
                    send_file_not_found();
                }
            }
            // ========================================================================================================================
        } else {
            if ($component === 'tag') {
                if ($filearea === 'description' and $context->contextlevel == CONTEXT_SYSTEM) {
                    // All tag descriptions are going to be public but we still need to respect forcelogin
                    if ($CFG->forcelogin) {
                        require_login();
                    }
                    $fullpath = "/{$context->id}/tag/description/" . implode('/', $args);
                    if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) {
                        send_file_not_found();
                    }
                    \core\session\manager::write_close();
                    // Unlock session during file serving.
                    send_stored_file($file, 60 * 60, 0, true, array('preview' => $preview));
                } else {
                    send_file_not_found();
                }
                // ========================================================================================================================
            } else {
                if ($component === 'badges') {
                    require_once $CFG->libdir . '/badgeslib.php';
                    $badgeid = (int) array_shift($args);
                    $badge = new badge($badgeid);
                    $filename = array_pop($args);
                    if ($filearea === 'badgeimage') {
                        if ($filename !== 'f1' && $filename !== 'f2') {
                            send_file_not_found();
                        }
                        if (!($file = $fs->get_file($context->id, 'badges', 'badgeimage', $badge->id, '/', $filename . '.png'))) {
                            send_file_not_found();
                        }
                        \core\session\manager::write_close();
                        send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview));
                    } else {
                        if ($filearea === 'userbadge' and $context->contextlevel == CONTEXT_USER) {
                            if (!($file = $fs->get_file($context->id, 'badges', 'userbadge', $badge->id, '/', $filename . '.png'))) {
                                send_file_not_found();
                            }
                            \core\session\manager::write_close();
                            send_stored_file($file, 60 * 60, 0, true, array('preview' => $preview));
                        }
                    }
                    // ========================================================================================================================
                } else {
                    if ($component === 'calendar') {
                        if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_SYSTEM) {
                            // All events here are public the one requirement is that we respect forcelogin
                            if ($CFG->forcelogin) {
                                require_login();
                            }
                            // Get the event if from the args array
                            $eventid = array_shift($args);
                            // Load the event from the database
                            if (!($event = $DB->get_record('event', array('id' => (int) $eventid, 'eventtype' => 'site')))) {
                                send_file_not_found();
                            }
                            // Get the file and serve if successful
                            $filename = array_pop($args);
                            $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                            if (!($file = $fs->get_file($context->id, $component, $filearea, $eventid, $filepath, $filename)) or $file->is_directory()) {
                                send_file_not_found();
                            }
                            \core\session\manager::write_close();
                            // Unlock session during file serving.
                            send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview));
                        } else {
                            if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_USER) {
                                // Must be logged in, if they are not then they obviously can't be this user
                                require_login();
                                // Don't want guests here, potentially saves a DB call
                                if (isguestuser()) {
                                    send_file_not_found();
                                }
                                // Get the event if from the args array
                                $eventid = array_shift($args);
                                // Load the event from the database - user id must match
                                if (!($event = $DB->get_record('event', array('id' => (int) $eventid, 'userid' => $USER->id, 'eventtype' => 'user')))) {
                                    send_file_not_found();
                                }
                                // Get the file and serve if successful
                                $filename = array_pop($args);
                                $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                if (!($file = $fs->get_file($context->id, $component, $filearea, $eventid, $filepath, $filename)) or $file->is_directory()) {
                                    send_file_not_found();
                                }
                                \core\session\manager::write_close();
                                // Unlock session during file serving.
                                send_stored_file($file, 0, 0, true, array('preview' => $preview));
                            } else {
                                if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_COURSE) {
                                    // Respect forcelogin and require login unless this is the site.... it probably
                                    // should NEVER be the site
                                    if ($CFG->forcelogin || $course->id != SITEID) {
                                        require_login($course);
                                    }
                                    // Must be able to at least view the course. This does not apply to the front page.
                                    if ($course->id != SITEID && !is_enrolled($context) && !is_viewing($context)) {
                                        //TODO: hmm, do we really want to block guests here?
                                        send_file_not_found();
                                    }
                                    // Get the event id
                                    $eventid = array_shift($args);
                                    // Load the event from the database we need to check whether it is
                                    // a) valid course event
                                    // b) a group event
                                    // Group events use the course context (there is no group context)
                                    if (!($event = $DB->get_record('event', array('id' => (int) $eventid, 'courseid' => $course->id)))) {
                                        send_file_not_found();
                                    }
                                    // If its a group event require either membership of view all groups capability
                                    if ($event->eventtype === 'group') {
                                        if (!has_capability('moodle/site:accessallgroups', $context) && !groups_is_member($event->groupid, $USER->id)) {
                                            send_file_not_found();
                                        }
                                    } else {
                                        if ($event->eventtype === 'course' || $event->eventtype === 'site') {
                                            // Ok. Please note that the event type 'site' still uses a course context.
                                        } else {
                                            // Some other type.
                                            send_file_not_found();
                                        }
                                    }
                                    // If we get this far we can serve the file
                                    $filename = array_pop($args);
                                    $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                    if (!($file = $fs->get_file($context->id, $component, $filearea, $eventid, $filepath, $filename)) or $file->is_directory()) {
                                        send_file_not_found();
                                    }
                                    \core\session\manager::write_close();
                                    // Unlock session during file serving.
                                    send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview));
                                } else {
                                    send_file_not_found();
                                }
                            }
                        }
                        // ========================================================================================================================
                    } else {
                        if ($component === 'user') {
                            if ($filearea === 'icon' and $context->contextlevel == CONTEXT_USER) {
                                if (count($args) == 1) {
                                    $themename = theme_config::DEFAULT_THEME;
                                    $filename = array_shift($args);
                                } else {
                                    $themename = array_shift($args);
                                    $filename = array_shift($args);
                                }
                                // fix file name automatically
                                if ($filename !== 'f1' and $filename !== 'f2' and $filename !== 'f3') {
                                    $filename = 'f1';
                                }
                                if ((!empty($CFG->forcelogin) and !isloggedin()) || !empty($CFG->forceloginforprofileimage) && (!isloggedin() || isguestuser())) {
                                    // protect images if login required and not logged in;
                                    // also if login is required for profile images and is not logged in or guest
                                    // do not use require_login() because it is expensive and not suitable here anyway
                                    $theme = theme_config::load($themename);
                                    redirect($theme->pix_url('u/' . $filename, 'moodle'));
                                    // intentionally not cached
                                }
                                if (!($file = $fs->get_file($context->id, 'user', 'icon', 0, '/', $filename . '.png'))) {
                                    if (!($file = $fs->get_file($context->id, 'user', 'icon', 0, '/', $filename . '.jpg'))) {
                                        if ($filename === 'f3') {
                                            // f3 512x512px was introduced in 2.3, there might be only the smaller version.
                                            if (!($file = $fs->get_file($context->id, 'user', 'icon', 0, '/', 'f1.png'))) {
                                                $file = $fs->get_file($context->id, 'user', 'icon', 0, '/', 'f1.jpg');
                                            }
                                        }
                                    }
                                }
                                if (!$file) {
                                    // bad reference - try to prevent future retries as hard as possible!
                                    if ($user = $DB->get_record('user', array('id' => $context->instanceid), 'id, picture')) {
                                        if ($user->picture > 0) {
                                            $DB->set_field('user', 'picture', 0, array('id' => $user->id));
                                        }
                                    }
                                    // no redirect here because it is not cached
                                    $theme = theme_config::load($themename);
                                    $imagefile = $theme->resolve_image_location('u/' . $filename, 'moodle', null);
                                    send_file($imagefile, basename($imagefile), 60 * 60 * 24 * 14);
                                }
                                $options = array('preview' => $preview);
                                if (empty($CFG->forcelogin) && empty($CFG->forceloginforprofileimage)) {
                                    // Profile images should be cache-able by both browsers and proxies according
                                    // to $CFG->forcelogin and $CFG->forceloginforprofileimage.
                                    $options['cacheability'] = 'public';
                                }
                                send_stored_file($file, 60 * 60 * 24 * 365, 0, false, $options);
                                // enable long caching, there are many images on each page
                            } else {
                                if ($filearea === 'private' and $context->contextlevel == CONTEXT_USER) {
                                    require_login();
                                    if (isguestuser()) {
                                        send_file_not_found();
                                    }
                                    if ($USER->id !== $context->instanceid) {
                                        send_file_not_found();
                                    }
                                    $filename = array_pop($args);
                                    $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                    if (!($file = $fs->get_file($context->id, $component, $filearea, 0, $filepath, $filename)) or $file->is_directory()) {
                                        send_file_not_found();
                                    }
                                    \core\session\manager::write_close();
                                    // Unlock session during file serving.
                                    send_stored_file($file, 0, 0, true, array('preview' => $preview));
                                    // must force download - security!
                                } else {
                                    if ($filearea === 'profile' and $context->contextlevel == CONTEXT_USER) {
                                        if ($CFG->forcelogin) {
                                            require_login();
                                        }
                                        $userid = $context->instanceid;
                                        if ($USER->id == $userid) {
                                            // always can access own
                                        } else {
                                            if (!empty($CFG->forceloginforprofiles)) {
                                                require_login();
                                                if (isguestuser()) {
                                                    send_file_not_found();
                                                }
                                                // we allow access to site profile of all course contacts (usually teachers)
                                                if (!has_coursecontact_role($userid) && !has_capability('moodle/user:viewdetails', $context)) {
                                                    send_file_not_found();
                                                }
                                                $canview = false;
                                                if (has_capability('moodle/user:viewdetails', $context)) {
                                                    $canview = true;
                                                } else {
                                                    $courses = enrol_get_my_courses();
                                                }
                                                while (!$canview && count($courses) > 0) {
                                                    $course = array_shift($courses);
                                                    if (has_capability('moodle/user:viewdetails', context_course::instance($course->id))) {
                                                        $canview = true;
                                                    }
                                                }
                                            }
                                        }
                                        $filename = array_pop($args);
                                        $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                        if (!($file = $fs->get_file($context->id, $component, $filearea, 0, $filepath, $filename)) or $file->is_directory()) {
                                            send_file_not_found();
                                        }
                                        \core\session\manager::write_close();
                                        // Unlock session during file serving.
                                        send_stored_file($file, 0, 0, true, array('preview' => $preview));
                                        // must force download - security!
                                    } else {
                                        if ($filearea === 'profile' and $context->contextlevel == CONTEXT_COURSE) {
                                            $userid = (int) array_shift($args);
                                            $usercontext = context_user::instance($userid);
                                            if ($CFG->forcelogin) {
                                                require_login();
                                            }
                                            if (!empty($CFG->forceloginforprofiles)) {
                                                require_login();
                                                if (isguestuser()) {
                                                    print_error('noguest');
                                                }
                                                //TODO: review this logic of user profile access prevention
                                                if (!has_coursecontact_role($userid) and !has_capability('moodle/user:viewdetails', $usercontext)) {
                                                    print_error('usernotavailable');
                                                }
                                                if (!has_capability('moodle/user:viewdetails', $context) && !has_capability('moodle/user:viewdetails', $usercontext)) {
                                                    print_error('cannotviewprofile');
                                                }
                                                if (!is_enrolled($context, $userid)) {
                                                    print_error('notenrolledprofile');
                                                }
                                                if (groups_get_course_groupmode($course) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
                                                    print_error('groupnotamember');
                                                }
                                            }
                                            $filename = array_pop($args);
                                            $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                            if (!($file = $fs->get_file($usercontext->id, 'user', 'profile', 0, $filepath, $filename)) or $file->is_directory()) {
                                                send_file_not_found();
                                            }
                                            \core\session\manager::write_close();
                                            // Unlock session during file serving.
                                            send_stored_file($file, 0, 0, true, array('preview' => $preview));
                                            // must force download - security!
                                        } else {
                                            if ($filearea === 'backup' and $context->contextlevel == CONTEXT_USER) {
                                                require_login();
                                                if (isguestuser()) {
                                                    send_file_not_found();
                                                }
                                                $userid = $context->instanceid;
                                                if ($USER->id != $userid) {
                                                    send_file_not_found();
                                                }
                                                $filename = array_pop($args);
                                                $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                                if (!($file = $fs->get_file($context->id, 'user', 'backup', 0, $filepath, $filename)) or $file->is_directory()) {
                                                    send_file_not_found();
                                                }
                                                \core\session\manager::write_close();
                                                // Unlock session during file serving.
                                                send_stored_file($file, 0, 0, true, array('preview' => $preview));
                                                // must force download - security!
                                            } else {
                                                send_file_not_found();
                                            }
                                        }
                                    }
                                }
                            }
                            // ========================================================================================================================
                        } else {
                            if ($component === 'coursecat') {
                                if ($context->contextlevel != CONTEXT_COURSECAT) {
                                    send_file_not_found();
                                }
                                if ($filearea === 'description') {
                                    if ($CFG->forcelogin) {
                                        // no login necessary - unless login forced everywhere
                                        require_login();
                                    }
                                    $filename = array_pop($args);
                                    $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                    if (!($file = $fs->get_file($context->id, 'coursecat', 'description', 0, $filepath, $filename)) or $file->is_directory()) {
                                        send_file_not_found();
                                    }
                                    \core\session\manager::write_close();
                                    // Unlock session during file serving.
                                    send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview));
                                } else {
                                    send_file_not_found();
                                }
                                // ========================================================================================================================
                            } else {
                                if ($component === 'course') {
                                    if ($context->contextlevel != CONTEXT_COURSE) {
                                        send_file_not_found();
                                    }
                                    if ($filearea === 'summary' || $filearea === 'overviewfiles') {
                                        if ($CFG->forcelogin) {
                                            require_login();
                                        }
                                        $filename = array_pop($args);
                                        $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                        if (!($file = $fs->get_file($context->id, 'course', $filearea, 0, $filepath, $filename)) or $file->is_directory()) {
                                            send_file_not_found();
                                        }
                                        \core\session\manager::write_close();
                                        // Unlock session during file serving.
                                        send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview));
                                    } else {
                                        if ($filearea === 'section') {
                                            if ($CFG->forcelogin) {
                                                require_login($course);
                                            } else {
                                                if ($course->id != SITEID) {
                                                    require_login($course);
                                                }
                                            }
                                            $sectionid = (int) array_shift($args);
                                            if (!($section = $DB->get_record('course_sections', array('id' => $sectionid, 'course' => $course->id)))) {
                                                send_file_not_found();
                                            }
                                            $filename = array_pop($args);
                                            $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                            if (!($file = $fs->get_file($context->id, 'course', 'section', $sectionid, $filepath, $filename)) or $file->is_directory()) {
                                                send_file_not_found();
                                            }
                                            \core\session\manager::write_close();
                                            // Unlock session during file serving.
                                            send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview));
                                        } else {
                                            send_file_not_found();
                                        }
                                    }
                                } else {
                                    if ($component === 'cohort') {
                                        $cohortid = (int) array_shift($args);
                                        $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
                                        $cohortcontext = context::instance_by_id($cohort->contextid);
                                        // The context in the file URL must be either cohort context or context of the course underneath the cohort's context.
                                        if ($context->id != $cohort->contextid && ($context->contextlevel != CONTEXT_COURSE || !in_array($cohort->contextid, $context->get_parent_context_ids()))) {
                                            send_file_not_found();
                                        }
                                        // User is able to access cohort if they have view cap on cohort level or
                                        // the cohort is visible and they have view cap on course level.
                                        $canview = has_capability('moodle/cohort:view', $cohortcontext) || $cohort->visible && has_capability('moodle/cohort:view', $context);
                                        if ($filearea === 'description' && $canview) {
                                            $filename = array_pop($args);
                                            $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                            if (($file = $fs->get_file($cohortcontext->id, 'cohort', 'description', $cohort->id, $filepath, $filename)) && !$file->is_directory()) {
                                                \core\session\manager::write_close();
                                                // Unlock session during file serving.
                                                send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview));
                                            }
                                        }
                                        send_file_not_found();
                                    } else {
                                        if ($component === 'group') {
                                            if ($context->contextlevel != CONTEXT_COURSE) {
                                                send_file_not_found();
                                            }
                                            require_course_login($course, true, null, false);
                                            $groupid = (int) array_shift($args);
                                            $group = $DB->get_record('groups', array('id' => $groupid, 'courseid' => $course->id), '*', MUST_EXIST);
                                            if ($course->groupmodeforce and $course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context) and !groups_is_member($group->id, $USER->id)) {
                                                // do not allow access to separate group info if not member or teacher
                                                send_file_not_found();
                                            }
                                            if ($filearea === 'description') {
                                                require_login($course);
                                                $filename = array_pop($args);
                                                $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                                if (!($file = $fs->get_file($context->id, 'group', 'description', $group->id, $filepath, $filename)) or $file->is_directory()) {
                                                    send_file_not_found();
                                                }
                                                \core\session\manager::write_close();
                                                // Unlock session during file serving.
                                                send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview));
                                            } else {
                                                if ($filearea === 'icon') {
                                                    $filename = array_pop($args);
                                                    if ($filename !== 'f1' and $filename !== 'f2') {
                                                        send_file_not_found();
                                                    }
                                                    if (!($file = $fs->get_file($context->id, 'group', 'icon', $group->id, '/', $filename . '.png'))) {
                                                        if (!($file = $fs->get_file($context->id, 'group', 'icon', $group->id, '/', $filename . '.jpg'))) {
                                                            send_file_not_found();
                                                        }
                                                    }
                                                    \core\session\manager::write_close();
                                                    // Unlock session during file serving.
                                                    send_stored_file($file, 60 * 60, 0, false, array('preview' => $preview));
                                                } else {
                                                    send_file_not_found();
                                                }
                                            }
                                        } else {
                                            if ($component === 'grouping') {
                                                if ($context->contextlevel != CONTEXT_COURSE) {
                                                    send_file_not_found();
                                                }
                                                require_login($course);
                                                $groupingid = (int) array_shift($args);
                                                // note: everybody has access to grouping desc images for now
                                                if ($filearea === 'description') {
                                                    $filename = array_pop($args);
                                                    $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                                    if (!($file = $fs->get_file($context->id, 'grouping', 'description', $groupingid, $filepath, $filename)) or $file->is_directory()) {
                                                        send_file_not_found();
                                                    }
                                                    \core\session\manager::write_close();
                                                    // Unlock session during file serving.
                                                    send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview));
                                                } else {
                                                    send_file_not_found();
                                                }
                                                // ========================================================================================================================
                                            } else {
                                                if ($component === 'backup') {
                                                    if ($filearea === 'course' and $context->contextlevel == CONTEXT_COURSE) {
                                                        require_login($course);
                                                        require_capability('moodle/backup:downloadfile', $context);
                                                        $filename = array_pop($args);
                                                        $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                                        if (!($file = $fs->get_file($context->id, 'backup', 'course', 0, $filepath, $filename)) or $file->is_directory()) {
                                                            send_file_not_found();
                                                        }
                                                        \core\session\manager::write_close();
                                                        // Unlock session during file serving.
                                                        send_stored_file($file, 0, 0, $forcedownload, array('preview' => $preview));
                                                    } else {
                                                        if ($filearea === 'section' and $context->contextlevel == CONTEXT_COURSE) {
                                                            require_login($course);
                                                            require_capability('moodle/backup:downloadfile', $context);
                                                            $sectionid = (int) array_shift($args);
                                                            $filename = array_pop($args);
                                                            $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                                            if (!($file = $fs->get_file($context->id, 'backup', 'section', $sectionid, $filepath, $filename)) or $file->is_directory()) {
                                                                send_file_not_found();
                                                            }
                                                            \core\session\manager::write_close();
                                                            send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview));
                                                        } else {
                                                            if ($filearea === 'activity' and $context->contextlevel == CONTEXT_MODULE) {
                                                                require_login($course, false, $cm);
                                                                require_capability('moodle/backup:downloadfile', $context);
                                                                $filename = array_pop($args);
                                                                $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                                                if (!($file = $fs->get_file($context->id, 'backup', 'activity', 0, $filepath, $filename)) or $file->is_directory()) {
                                                                    send_file_not_found();
                                                                }
                                                                \core\session\manager::write_close();
                                                                send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview));
                                                            } else {
                                                                if ($filearea === 'automated' and $context->contextlevel == CONTEXT_COURSE) {
                                                                    // Backup files that were generated by the automated backup systems.
                                                                    require_login($course);
                                                                    require_capability('moodle/site:config', $context);
                                                                    $filename = array_pop($args);
                                                                    $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                                                    if (!($file = $fs->get_file($context->id, 'backup', 'automated', 0, $filepath, $filename)) or $file->is_directory()) {
                                                                        send_file_not_found();
                                                                    }
                                                                    \core\session\manager::write_close();
                                                                    // Unlock session during file serving.
                                                                    send_stored_file($file, 0, 0, $forcedownload, array('preview' => $preview));
                                                                } else {
                                                                    send_file_not_found();
                                                                }
                                                            }
                                                        }
                                                    }
                                                    // ========================================================================================================================
                                                } else {
                                                    if ($component === 'question') {
                                                        require_once $CFG->libdir . '/questionlib.php';
                                                        question_pluginfile($course, $context, 'question', $filearea, $args, $forcedownload);
                                                        send_file_not_found();
                                                        // ========================================================================================================================
                                                    } else {
                                                        if ($component === 'grading') {
                                                            if ($filearea === 'description') {
                                                                // files embedded into the form definition description
                                                                if ($context->contextlevel == CONTEXT_SYSTEM) {
                                                                    require_login();
                                                                } else {
                                                                    if ($context->contextlevel >= CONTEXT_COURSE) {
                                                                        require_login($course, false, $cm);
                                                                    } else {
                                                                        send_file_not_found();
                                                                    }
                                                                }
                                                                $formid = (int) array_shift($args);
                                                                $sql = "SELECT ga.id\n                FROM {grading_areas} ga\n                JOIN {grading_definitions} gd ON (gd.areaid = ga.id)\n                WHERE gd.id = ? AND ga.contextid = ?";
                                                                $areaid = $DB->get_field_sql($sql, array($formid, $context->id), IGNORE_MISSING);
                                                                if (!$areaid) {
                                                                    send_file_not_found();
                                                                }
                                                                $fullpath = "/{$context->id}/{$component}/{$filearea}/{$formid}/" . implode('/', $args);
                                                                if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) {
                                                                    send_file_not_found();
                                                                }
                                                                \core\session\manager::write_close();
                                                                // Unlock session during file serving.
                                                                send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview));
                                                            }
                                                            // ========================================================================================================================
                                                        } else {
                                                            if (strpos($component, 'mod_') === 0) {
                                                                $modname = substr($component, 4);
                                                                if (!file_exists("{$CFG->dirroot}/mod/{$modname}/lib.php")) {
                                                                    send_file_not_found();
                                                                }
                                                                require_once "{$CFG->dirroot}/mod/{$modname}/lib.php";
                                                                if ($context->contextlevel == CONTEXT_MODULE) {
                                                                    if ($cm->modname !== $modname) {
                                                                        // somebody tries to gain illegal access, cm type must match the component!
                                                                        send_file_not_found();
                                                                    }
                                                                }
                                                                if ($filearea === 'intro') {
                                                                    if (!plugin_supports('mod', $modname, FEATURE_MOD_INTRO, true)) {
                                                                        send_file_not_found();
                                                                    }
                                                                    require_course_login($course, true, $cm);
                                                                    // all users may access it
                                                                    $filename = array_pop($args);
                                                                    $filepath = $args ? '/' . implode('/', $args) . '/' : '/';
                                                                    if (!($file = $fs->get_file($context->id, 'mod_' . $modname, 'intro', 0, $filepath, $filename)) or $file->is_directory()) {
                                                                        send_file_not_found();
                                                                    }
                                                                    // finally send the file
                                                                    send_stored_file($file, null, 0, false, array('preview' => $preview));
                                                                }
                                                                $filefunction = $component . '_pluginfile';
                                                                $filefunctionold = $modname . '_pluginfile';
                                                                if (function_exists($filefunction)) {
                                                                    // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found"
                                                                    $filefunction($course, $cm, $context, $filearea, $args, $forcedownload, array('preview' => $preview));
                                                                } else {
                                                                    if (function_exists($filefunctionold)) {
                                                                        // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found"
                                                                        $filefunctionold($course, $cm, $context, $filearea, $args, $forcedownload, array('preview' => $preview));
                                                                    }
                                                                }
                                                                send_file_not_found();
                                                                // ========================================================================================================================
                                                            } else {
                                                                if (strpos($component, 'block_') === 0) {
                                                                    $blockname = substr($component, 6);
                                                                    // note: no more class methods in blocks please, that is ....
                                                                    if (!file_exists("{$CFG->dirroot}/blocks/{$blockname}/lib.php")) {
                                                                        send_file_not_found();
                                                                    }
                                                                    require_once "{$CFG->dirroot}/blocks/{$blockname}/lib.php";
                                                                    if ($context->contextlevel == CONTEXT_BLOCK) {
                                                                        $birecord = $DB->get_record('block_instances', array('id' => $context->instanceid), '*', MUST_EXIST);
                                                                        if ($birecord->blockname !== $blockname) {
                                                                            // somebody tries to gain illegal access, cm type must match the component!
                                                                            send_file_not_found();
                                                                        }
                                                                        if ($context->get_course_context(false)) {
                                                                            // If block is in course context, then check if user has capability to access course.
                                                                            require_course_login($course);
                                                                        } else {
                                                                            if ($CFG->forcelogin) {
                                                                                // If user is logged out, bp record will not be visible, even if the user would have access if logged in.
                                                                                require_login();
                                                                            }
                                                                        }
                                                                        $bprecord = $DB->get_record('block_positions', array('contextid' => $context->id, 'blockinstanceid' => $context->instanceid));
                                                                        // User can't access file, if block is hidden or doesn't have block:view capability
                                                                        if ($bprecord && !$bprecord->visible || !has_capability('moodle/block:view', $context)) {
                                                                            send_file_not_found();
                                                                        }
                                                                    } else {
                                                                        $birecord = null;
                                                                    }
                                                                    $filefunction = $component . '_pluginfile';
                                                                    if (function_exists($filefunction)) {
                                                                        // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found"
                                                                        $filefunction($course, $birecord, $context, $filearea, $args, $forcedownload, array('preview' => $preview));
                                                                    }
                                                                    send_file_not_found();
                                                                    // ========================================================================================================================
                                                                } else {
                                                                    if (strpos($component, '_') === false) {
                                                                        // all core subsystems have to be specified above, no more guessing here!
                                                                        send_file_not_found();
                                                                    } else {
                                                                        // try to serve general plugin file in arbitrary context
                                                                        $dir = core_component::get_component_directory($component);
                                                                        if (!file_exists("{$dir}/lib.php")) {
                                                                            send_file_not_found();
                                                                        }
                                                                        include_once "{$dir}/lib.php";
                                                                        $filefunction = $component . '_pluginfile';
                                                                        if (function_exists($filefunction)) {
                                                                            // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found"
                                                                            $filefunction($course, $cm, $context, $filearea, $args, $forcedownload, array('preview' => $preview));
                                                                        }
                                                                        send_file_not_found();
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
Ejemplo n.º 16
0
function report_comments_getcoursecomments($courseid, $sort = 'date')
{
    global $CFG, $DB;
    $formatoptions = array('overflowdiv' => true);
    $strftimeformat = get_string('strftimerecentfull', 'langconfig');
    $context = context_course::instance($courseid);
    $comments = $DB->get_records('comments', array('contextid' => $context->id));
    foreach ($comments as $comment) {
        $user = $DB->get_record('user', array('id' => $comment->userid), 'firstname, lastname');
        $url = new moodle_url('/report/comments/index.php', array('id' => $comment->userid, 'course' => $courseid));
        $comment->fullname = html_writer::link($url, $user->firstname . ' ' . $user->lastname);
        $comment->time = userdate($comment->timecreated, $strftimeformat);
        $url = new moodle_url('/course/view.php', array('id' => $courseid));
        $comment->content = html_writer::link($url, format_text($comment->content, $comment->format, $formatoptions));
    }
    $rawmods = get_course_mods($courseid);
    foreach ($rawmods as $mod) {
        if ($context = $DB->get_record('context', array('instanceid' => $mod->id, 'contextlevel' => CONTEXT_MODULE))) {
            if ($modcomments = $DB->get_records('comments', array('contextid' => $context->id))) {
                foreach ($modcomments as $comment) {
                    $user = $DB->get_record('user', array('id' => $comment->userid), 'firstname, lastname');
                    $url = new moodle_url('/report/comments/index.php', array('course' => $courseid, 'id' => $comment->userid));
                    $comment->fullname = html_writer::link($url, $user->firstname . ' ' . $user->lastname);
                    $comment->time = userdate($comment->timecreated, $strftimeformat);
                    $base = core_component::get_component_directory('mod_' . $mod->modname);
                    if (file_exists("{$base}/view.php")) {
                        $base = substr($base, strlen($CFG->dirroot));
                        $url = new moodle_url("{$base}/view.php", array('id' => $mod->id));
                        $comment->content = html_writer::link($url, format_text($comment->content, $comment->format, $formatoptions));
                    } else {
                        $comment->content = format_text($comment->content, $comment->format, $formatoptions);
                    }
                    $comments[] = $comment;
                }
            }
        }
    }
    switch ($sort) {
        case 'date':
            usort($comments, "cmpdate");
            break;
        case 'content':
            usort($comments, "cmpcontent");
            break;
        case 'author':
            usort($comments, "cmpid");
            break;
    }
    return $comments;
}
Ejemplo n.º 17
0
 /**
  * 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];
 }
Ejemplo n.º 18
0
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
require_once __DIR__ . '/../../config.php';
require_once $CFG->libdir . '/adminlib.php';
// Required parameters.
$eventname = required_param('eventname', PARAM_RAW);
admin_externalpage_setup('reporteventlists');
// Retrieve all events in a list.
$completelist = report_eventlist_list_generator::get_all_events_list(false);
// Check that $eventname is a valid event.
if (!array_key_exists($eventname, $completelist)) {
    print_error('errorinvalidevent', 'report_eventlist');
}
// Break up the full event name to usable parts.
$component = explode('\\', $eventname);
$directory = core_component::get_component_directory($component[1]);
// File and directory information.
$directory = $directory . '/classes/event';
// Verify that the directory is valid.
if (!is_dir($directory)) {
    print_error('errorinvaliddirectory', 'report_eventlist');
}
$filename = end($component);
$eventfiles = $directory . '/' . $filename . '.php';
$title = $eventname::get_name_with_info();
// Define event information.
$eventinformation = array('title' => $title);
$eventcontents = file_get_contents($eventfiles);
$eventinformation['filecontents'] = $eventcontents;
$ref = new \ReflectionClass($eventname);
$eventinformation['explanation'] = $eventname::get_explanation($eventname);
Ejemplo n.º 19
0
 public function test_get_component_directory()
 {
     $plugintypes = core_component::get_plugin_types();
     foreach ($plugintypes as $plugintype => $fulldir) {
         $plugins = core_component::get_plugin_list($plugintype);
         foreach ($plugins as $pluginname => $plugindir) {
             $this->assertSame($plugindir, core_component::get_component_directory($plugintype . '_' . $pluginname));
         }
     }
     $subsystems = core_component::get_core_subsystems();
     foreach ($subsystems as $subsystem => $fulldir) {
         $this->assertSame($fulldir, core_component::get_component_directory('core_' . $subsystem));
     }
 }
Ejemplo n.º 20
0
\core\session\manager::set_user($user);
//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');
        }
    }
Ejemplo n.º 21
0
/**
 * Returns the human-readable, translated version of the capability.
 * Basically a big switch statement.
 *
 * @param string $capabilityname e.g. mod/choice:readresponses
 * @return string
 */
function get_capability_string($capabilityname) {

    // Typical capability name is 'plugintype/pluginname:capabilityname'
    list($type, $name, $capname) = preg_split('|[/:]|', $capabilityname);

    if ($type === 'moodle') {
        $component = 'core_role';
    } else if ($type === 'quizreport') {
        //ugly hack!!
        $component = 'quiz_'.$name;
    } else {
        $component = $type.'_'.$name;
    }

    $stringname = $name.':'.$capname;

    if ($component === 'core_role' or get_string_manager()->string_exists($stringname, $component)) {
        return get_string($stringname, $component);
    }

    $dir = core_component::get_component_directory($component);
    if (!file_exists($dir)) {
        // plugin broken or does not exist, do not bother with printing of debug message
        return $capabilityname.' ???';
    }

    // something is wrong in plugin, better print debug
    return get_string($stringname, $component);
}
Ejemplo n.º 22
0
/**
 * Adds a specified user to a group
 *
 * @param mixed $grouporid  The group id or group object
 * @param mixed $userorid   The user id or user object
 * @param string $component Optional component name e.g. 'enrol_imsenterprise'
 * @param int $itemid Optional itemid associated with component
 * @return bool True if user added successfully or the user is already a
 * member of the group, false otherwise.
 */
function groups_add_member($grouporid, $userorid, $component = null, $itemid = 0)
{
    global $DB;
    if (is_object($userorid)) {
        $userid = $userorid->id;
        $user = $userorid;
        if (!isset($user->deleted)) {
            $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
        }
    } else {
        $userid = $userorid;
        $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
    }
    if ($user->deleted) {
        return false;
    }
    if (is_object($grouporid)) {
        $groupid = $grouporid->id;
        $group = $grouporid;
    } else {
        $groupid = $grouporid;
        $group = $DB->get_record('groups', array('id' => $groupid), '*', MUST_EXIST);
    }
    // Check if the user a participant of the group course.
    $context = context_course::instance($group->courseid);
    if (!is_enrolled($context, $userid)) {
        return false;
    }
    if (groups_is_member($groupid, $userid)) {
        return true;
    }
    $member = new stdClass();
    $member->groupid = $groupid;
    $member->userid = $userid;
    $member->timeadded = time();
    $member->component = '';
    $member->itemid = 0;
    // Check the component exists if specified
    if (!empty($component)) {
        $dir = core_component::get_component_directory($component);
        if ($dir && is_dir($dir)) {
            // Component exists and can be used
            $member->component = $component;
            $member->itemid = $itemid;
        } else {
            throw new coding_exception('Invalid call to groups_add_member(). An invalid component was specified');
        }
    }
    if ($itemid !== 0 && empty($member->component)) {
        // An itemid can only be specified if a valid component was found
        throw new coding_exception('Invalid call to groups_add_member(). A component must be specified if an itemid is given');
    }
    $DB->insert_record('groups_members', $member);
    // Update group info, and group object.
    $DB->set_field('groups', 'timemodified', $member->timeadded, array('id' => $groupid));
    $group->timemodified = $member->timeadded;
    // Trigger group event.
    $params = array('context' => $context, 'objectid' => $groupid, 'relateduserid' => $userid, 'other' => array('component' => $member->component, 'itemid' => $member->itemid));
    $event = \core\event\group_member_added::create($params);
    $event->add_record_snapshot('groups', $group);
    $event->trigger();
    return true;
}
Ejemplo n.º 23
0
/**
 * 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;
}
Ejemplo n.º 24
0
 /**
  * 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;
 }
Ejemplo n.º 25
0
 /**
  * Find the plugin info class for given type.
  *
  * @param string $type
  * @return string name of pluginfo class for give plugin type
  */
 public static function resolve_plugininfo_class($type)
 {
     $plugintypes = core_component::get_plugin_types();
     if (!isset($plugintypes[$type])) {
         return '\\core\\plugininfo\\orphaned';
     }
     $parent = core_component::get_subtype_parent($type);
     if ($parent) {
         $class = '\\' . $parent . '\\plugininfo\\' . $type;
         if (class_exists($class)) {
             $plugintypeclass = $class;
         } else {
             if ($dir = core_component::get_component_directory($parent)) {
                 // BC only - use namespace instead!
                 if (file_exists("{$dir}/adminlib.php")) {
                     global $CFG;
                     include_once "{$dir}/adminlib.php";
                 }
                 if (class_exists('plugininfo_' . $type)) {
                     $plugintypeclass = 'plugininfo_' . $type;
                     debugging('Class "' . $plugintypeclass . '" is deprecated, migrate to "' . $class . '"', DEBUG_DEVELOPER);
                 } else {
                     debugging('Subplugin type "' . $type . '" should define class "' . $class . '"', DEBUG_DEVELOPER);
                     $plugintypeclass = '\\core\\plugininfo\\general';
                 }
             } else {
                 $plugintypeclass = '\\core\\plugininfo\\general';
             }
         }
     } else {
         $class = '\\core\\plugininfo\\' . $type;
         if (class_exists($class)) {
             $plugintypeclass = $class;
         } else {
             debugging('All standard types including "' . $type . '" should have plugininfo class!', DEBUG_DEVELOPER);
             $plugintypeclass = '\\core\\plugininfo\\general';
         }
     }
     if (!in_array('core\\plugininfo\\base', class_parents($plugintypeclass))) {
         throw new coding_exception('Class ' . $plugintypeclass . ' must extend \\core\\plugininfo\\base');
     }
     return $plugintypeclass;
 }
Ejemplo n.º 26
0
 /**
  * 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(core_component::get_component_directory('core'))) {
         $moodlemodules = array_merge($moodlemodules, $module);
     }
     // Handle other core subsystems.
     $subsystems = core_component::get_core_subsystems();
     foreach ($subsystems as $subsystem => $path) {
         if (is_null($path)) {
             continue;
         }
         if ($module = $this->get_moodle_path_metadata($path)) {
             $moodlemodules = array_merge($moodlemodules, $module);
         }
     }
     // And finally the plugins.
     $plugintypes = core_component::get_plugin_types();
     foreach ($plugintypes as $plugintype => $pathroot) {
         $pluginlist = core_component::get_plugin_list($plugintype);
         foreach ($pluginlist as $plugin => $path) {
             if ($module = $this->get_moodle_path_metadata($path)) {
                 $moodlemodules = array_merge($moodlemodules, $module);
             }
         }
     }
     return $moodlemodules;
 }
Ejemplo n.º 27
0
 /**
  * Add subplugin structure for a given plugin to any element in the structure restore tree
  *
  * This method allows the injection of subplugins (of a specific plugin) parsing and proccessing
  * to any element in the restore structure.
  *
  * NOTE: Initially subplugins were only available for activities (mod), so only the
  * {@link restore_activity_structure_step} class had support for them, always
  * looking for /mod/modulenanme subplugins. This new method is a generalization of the
  * existing one for activities, supporting all subplugins injecting information everywhere.
  *
  * @param string $subplugintype type of subplugin as defined in plugin's db/subplugins.php.
  * @param restore_path_element $element element in the structure restore tree that
  *                              we are going to add subplugin information to.
  * @param string $plugintype type of the plugin.
  * @param string $pluginname name of the plugin.
  * @return void
  */
 protected function add_subplugin_structure($subplugintype, $element, $plugintype = null, $pluginname = null)
 {
     global $CFG;
     // This global declaration is required, because where we do require_once($backupfile);
     // That file may in turn try to do require_once($CFG->dirroot ...).
     // That worked in the past, we should keep it working.
     // Verify if this is a BC call for an activity restore. See NOTE above for this special case.
     if ($plugintype === null and $pluginname === null) {
         $plugintype = 'mod';
         $pluginname = $this->task->get_modulename();
         // TODO: Once all the calls have been changed to add both not null plugintype and pluginname, add a debugging here.
     }
     // Check the requested plugintype is a valid one.
     if (!array_key_exists($plugintype, core_component::get_plugin_types())) {
         throw new restore_step_exception('incorrect_plugin_type', $plugintype);
     }
     // Check the requested pluginname, for the specified plugintype, is a valid one.
     if (!array_key_exists($pluginname, core_component::get_plugin_list($plugintype))) {
         throw new restore_step_exception('incorrect_plugin_name', array($plugintype, $pluginname));
     }
     // Check the requested subplugintype is a valid one.
     $subpluginsfile = core_component::get_component_directory($plugintype . '_' . $pluginname) . '/db/subplugins.php';
     if (!file_exists($subpluginsfile)) {
         throw new restore_step_exception('plugin_missing_subplugins_php_file', array($plugintype, $pluginname));
     }
     include $subpluginsfile;
     if (!array_key_exists($subplugintype, $subplugins)) {
         throw new restore_step_exception('incorrect_subplugin_type', $subplugintype);
     }
     // Every subplugin optionally can have a common/parent subplugin
     // class for shared stuff.
     $parentclass = 'restore_' . $plugintype . '_' . $pluginname . '_' . $subplugintype . '_subplugin';
     $parentfile = core_component::get_component_directory($plugintype . '_' . $pluginname) . '/backup/moodle2/' . $parentclass . '.class.php';
     if (file_exists($parentfile)) {
         require_once $parentfile;
     }
     // Get all the restore path elements, looking across all the subplugin dirs.
     $subpluginsdirs = core_component::get_plugin_list($subplugintype);
     foreach ($subpluginsdirs as $name => $subpluginsdir) {
         $classname = 'restore_' . $subplugintype . '_' . $name . '_subplugin';
         $restorefile = $subpluginsdir . '/backup/moodle2/' . $classname . '.class.php';
         if (file_exists($restorefile)) {
             require_once $restorefile;
             $restoresubplugin = new $classname($subplugintype, $name, $this);
             // Add subplugin paths to the step.
             $this->prepare_pathelements($restoresubplugin->define_subplugin_structure($element));
         }
     }
 }
Ejemplo n.º 28
0
/**
 * Return exact absolute path to a plugin directory.
 *
 * @deprecated since 2.6, use core_component::normalize_component()
 *
 * @param string $component name such as 'moodle', 'mod_forum'
 * @return string full path to component directory; NULL if not found
 */
function get_component_directory($component)
{
    // NOTE: do not add any other debugging here, keep forever.
    return core_component::get_component_directory($component);
}
Ejemplo n.º 29
0
/**
 * Executes cron functions for a specific type of plugin.
 *
 * @param string $plugintype Plugin type (e.g. 'report')
 * @param string $description If specified, will display 'Starting (whatever)'
 *   and 'Finished (whatever)' lines, otherwise does not display
 */
function cron_execute_plugin_type($plugintype, $description = null)
{
    global $DB;
    // Get list from plugin => function for all plugins
    $plugins = get_plugin_list_with_function($plugintype, 'cron');
    // Modify list for backward compatibility (different files/names)
    $plugins = cron_bc_hack_plugin_functions($plugintype, $plugins);
    // Return if no plugins with cron function to process
    if (!$plugins) {
        return;
    }
    if ($description) {
        mtrace('Starting ' . $description);
    }
    foreach ($plugins as $component => $cronfunction) {
        $dir = core_component::get_component_directory($component);
        // Get cron period if specified in version.php, otherwise assume every cron
        $cronperiod = 0;
        if (file_exists("{$dir}/version.php")) {
            $plugin = new stdClass();
            include "{$dir}/version.php";
            if (isset($plugin->cron)) {
                $cronperiod = $plugin->cron;
            }
        }
        // Using last cron and cron period, don't run if it already ran recently
        $lastcron = get_config($component, 'lastcron');
        if ($cronperiod && $lastcron) {
            if ($lastcron + $cronperiod > time()) {
                // do not execute cron yet
                continue;
            }
        }
        mtrace('Processing cron function for ' . $component . '...');
        cron_trace_time_and_memory();
        $pre_dbqueries = $DB->perf_get_queries();
        $pre_time = microtime(true);
        $cronfunction();
        mtrace("done. (" . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries, " . round(microtime(true) - $pre_time, 2) . " seconds)");
        set_config('lastcron', time(), $component);
        @set_time_limit(0);
    }
    if ($description) {
        mtrace('Finished ' . $description);
    }
}
Ejemplo n.º 30
0
 /**
  * Use this editor for given element.
  *
  * @param string $elementid
  * @param array $options
  * @param null $fpoptions
  */
 public function use_editor($elementid, array $options = null, $fpoptions = null)
 {
     global $PAGE;
     $configstr = get_config('editor_atto', 'toolbar');
     $grouplines = explode("\n", $configstr);
     $groups = array();
     foreach ($grouplines as $groupline) {
         $line = explode('=', $groupline);
         if (count($line) > 1) {
             $group = trim(array_shift($line));
             $plugins = array_map('trim', explode(',', array_shift($line)));
             $groups[$group] = $plugins;
         }
     }
     $modules = array('moodle-editor_atto-editor');
     $options['context'] = empty($options['context']) ? context_system::instance() : $options['context'];
     $jsplugins = array();
     foreach ($groups as $group => $plugins) {
         $groupplugins = array();
         foreach ($plugins as $plugin) {
             // Do not die on missing plugin.
             if (!core_component::get_component_directory('atto_' . $plugin)) {
                 continue;
             }
             $jsplugin = array();
             $jsplugin['name'] = $plugin;
             $jsplugin['params'] = array();
             $modules[] = 'moodle-atto_' . $plugin . '-button';
             component_callback('atto_' . $plugin, 'strings_for_js');
             $extra = component_callback('atto_' . $plugin, 'params_for_js', array($elementid, $options, $fpoptions));
             if ($extra) {
                 $jsplugin = array_merge($jsplugin, $extra);
             }
             // We always need the plugin name.
             $PAGE->requires->string_for_js('pluginname', 'atto_' . $plugin);
             $groupplugins[] = $jsplugin;
         }
         $jsplugins[] = array('group' => $group, 'plugins' => $groupplugins);
     }
     $PAGE->requires->strings_for_js(array('editor_command_keycode', 'editor_control_keycode', 'plugin_title_shortcut', 'textrecovered', 'autosavefailed', 'autosavesucceeded', 'errortextrecovery'), 'editor_atto');
     $PAGE->requires->strings_for_js(array('warning', 'info'), 'moodle');
     $PAGE->requires->yui_module($modules, 'Y.M.editor_atto.Editor.init', array($this->get_init_params($elementid, $options, $fpoptions, $jsplugins)));
 }