���ѧۧݧ�ӧ�� �ާ֧ߧ֧էا֧� - ���֧էѧܧ�ڧ��ӧѧ�� - /home3/cpr76684/public_html/helper.php.tar
���ѧ٧ѧ�
home3/cpr76684/public_html/Aem/privacy/classes/local/request/helper.php 0000644 00000027526 15151252162 0021666 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * This file contains the core_privacy\local\request helper. * * @package core_privacy * @copyright 2018 Andrew Nicols <andrew@nicols.co.uk> * * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_privacy\local\request; use \core_privacy\local\request\writer; defined('MOODLE_INTERNAL') || die(); require_once($CFG->libdir . '/modinfolib.php'); require_once($CFG->dirroot . '/course/modlib.php'); /** * The core_privacy\local\request\helper class with useful shared functionality. * * @package core_privacy * @copyright 2018 Andrew Nicols <andrew@nicols.co.uk> * * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class helper { /** * Add core-controlled contexts which are related to a component but that component may know about. * * For example, most activities are not aware of activity completion, but the course implements it for them. * These should be included. * * @param int $userid The user being added for. * @param contextlist $contextlist The contextlist being appended to. * @return contextlist The final contextlist */ public static function add_shared_contexts_to_contextlist_for(int $userid, contextlist $contextlist) : contextlist { if (strpos($contextlist->get_component(), 'mod_') === 0) { // Activity modules support data stored by core about them - for example, activity completion. $contextlist = static::add_shared_contexts_to_contextlist_for_course_module($userid, $contextlist); } return $contextlist; } /** * Add core-controlled contexts which are related to a component but that component may know about. * * For example, most activities are not aware of activity completion, but the course implements it for them. * These should be included. * * @param \core_privacy\local\request\userlist $userlist * @return contextlist The final contextlist */ public static function add_shared_users_to_userlist(\core_privacy\local\request\userlist $userlist) { } /** * Handle export of standard data for a plugin which implements the null provider and does not normally store data * of its own. * * This is used in cases such as activities like mod_resource, which do not store their own data, but may still have * data on them (like Activity Completion). * * Any context provided in a contextlist should have base data exported as a minimum. * * @param approved_contextlist $contextlist The approved contexts to export information for. */ public static function export_data_for_null_provider(approved_contextlist $contextlist) { $user = $contextlist->get_user(); foreach ($contextlist as $context) { $data = static::get_context_data($context, $user); static::export_context_files($context, $user); writer::with_context($context)->export_data([], $data); } } /** * Handle removal of 'standard' data for any plugin. * * This will handle deletion for things such as activity completion. * * @param string $component The component being deleted for. * @param context $context The specific context to delete data for. */ public static function delete_data_for_all_users_in_context(string $component, \context $context) { // Activity modules support data stored by core about them - for example, activity completion. static::delete_data_for_all_users_in_context_course_module($component, $context); } /** * Delete all 'standard' user data for the specified user, in the specified contexts. * * This will handle deletion for things such as activity completion. * * @param approved_contextlist $contextlist The approved contexts and user information to delete information for. */ public static function delete_data_for_user(approved_contextlist $contextlist) { $component = $contextlist->get_component(); // Activity modules support data stored by core about them - for example, activity completion. static::delete_data_for_user_in_course_module($contextlist); } /** * Get all general data for this context. * * @param \context $context The context to retrieve data for. * @param \stdClass $user The user being written. * @return \stdClass */ public static function get_context_data(\context $context, \stdClass $user) : \stdClass { global $DB; $basedata = (object) []; if ($context instanceof \context_module) { return static::get_context_module_data($context, $user); } if ($context instanceof \context_block) { return static::get_context_block_data($context, $user); } return $basedata; } /** * Export all files for this context. * * @param \context $context The context to export files for. * @param \stdClass $user The user being written. * @return \stdClass */ public static function export_context_files(\context $context, \stdClass $user) { if ($context instanceof \context_module) { return static::export_context_module_files($context, $user); } } /** * Add core-controlled contexts which are related to a component but that component may know about. * * For example, most activities are not aware of activity completion, but the course implements it for them. * These should be included. * * @param int $userid The user being added for. * @param contextlist $contextlist The contextlist being appended to. * @return contextlist The final contextlist */ protected static function add_shared_contexts_to_contextlist_for_course_module(int $userid, contextlist $contextlist) : contextlist { // Fetch all contexts where the user has activity completion enabled. $sql = "SELECT c.id FROM {course_modules_completion} cmp INNER JOIN {course_modules} cm ON cm.id = cmp.coursemoduleid INNER JOIN {modules} m ON m.id = cm.module INNER JOIN {context} c ON c.instanceid = cm.id AND c.contextlevel = :contextlevel WHERE cmp.userid = :userid AND m.name = :modname"; $params = [ 'userid' => $userid, // Strip the mod_ from the name. 'modname' => substr($contextlist->get_component(), 4), 'contextlevel' => CONTEXT_MODULE, ]; $contextlist->add_from_sql($sql, $params); return $contextlist; } /** * Get all general data for the activity module at this context. * * @param \context_module $context The context to retrieve data for. * @param \stdClass $user The user being written. * @return \stdClass */ protected static function get_context_module_data(\context_module $context, \stdClass $user) : \stdClass { global $DB; $coursecontext = $context->get_course_context(); $modinfo = get_fast_modinfo($coursecontext->instanceid); $cm = $modinfo->cms[$context->instanceid]; $component = "mod_{$cm->modname}"; $course = $cm->get_course(); $moduledata = $DB->get_record($cm->modname, ['id' => $cm->instance]); $basedata = (object) [ 'name' => $cm->get_formatted_name(), ]; if (plugin_supports('mod', $cm->modname, FEATURE_MOD_INTRO, true)) { $intro = $moduledata->intro; $intro = writer::with_context($context) ->rewrite_pluginfile_urls([], $component, 'intro', 0, $intro); $options = [ 'noclean' => true, 'para' => false, 'context' => $context, 'overflowdiv' => true, ]; $basedata->intro = format_text($intro, $moduledata->introformat, $options); } // Completion tracking. $completiondata = \core_completion\privacy\provider::get_activity_completion_info($user, $course, $cm); if (isset($completiondata->completionstate)) { $basedata->completion = (object) [ 'state' => $completiondata->completionstate, ]; } return $basedata; } /** * Get all general data for the block at this context. * * @param \context_block $context The context to retrieve data for. * @param \stdClass $user The user being written. * @return \stdClass General data about this block instance. */ protected static function get_context_block_data(\context_block $context, \stdClass $user) : \stdClass { global $DB; $block = $DB->get_record('block_instances', ['id' => $context->instanceid]); $basedata = (object) [ 'blocktype' => get_string('pluginname', 'block_' . $block->blockname) ]; return $basedata; } /** * Get all general data for the activity module at this context. * * @param \context_module $context The context to retrieve data for. * @param \stdClass $user The user being written. * @return \stdClass */ protected static function export_context_module_files(\context_module $context, \stdClass $user) { $coursecontext = $context->get_course_context(); $modinfo = get_fast_modinfo($coursecontext->instanceid); $cm = $modinfo->cms[$context->instanceid]; $component = "mod_{$cm->modname}"; writer::with_context($context) // Export the files for the intro. ->export_area_files([], $component, 'intro', 0); } /** * Handle removal of 'standard' data for course modules. * * This will handle deletion for things such as activity completion. * * @param string $component The component being deleted for. * @param \context $context The context to delete all data for. */ public static function delete_data_for_all_users_in_context_course_module(string $component, \context $context) { global $DB; if ($context instanceof \context_module) { // Delete course completion data for this context. \core_completion\privacy\provider::delete_completion(null, null, $context->instanceid); } } /** * Delete all 'standard' user data for the specified user in course modules. * * This will handle deletion for things such as activity completion. * * @param approved_contextlist $contextlist The approved contexts and user information to delete information for. */ protected static function delete_data_for_user_in_course_module(approved_contextlist $contextlist) { global $DB; foreach ($contextlist as $context) { if ($context instanceof \context_module) { // Delete course completion data for this context. \core_completion\privacy\provider::delete_completion($contextlist->get_user(), null, $context->instanceid); } } } } home3/cpr76684/public_html/Aem/report/progress/classes/local/helper.php 0000644 00000005215 15151770356 0021701 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. namespace report_progress\local; /** * Helper for report progress. * * @package report_progress * @copyright 2021 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL Juv3 or later */ class helper { /** The default number of results to be shown per page. */ const COMPLETION_REPORT_PAGE = 25; /** * Get activities information by the activity include and activity order option. * * @param \completion_info $completion Completion information of course. * @param string $activityinclude Activity type for filtering. * @param string $activityorder Activity sort option. * @return array The available activity types and activities array after filtering and sorting. * @throws \coding_exception */ public static function get_activities_to_show(\completion_info $completion, string $activityinclude, string $activityorder): array { // Get all activity types. $activities = $completion->get_activities(); $availableactivitytypes = []; foreach ($activities as $activity) { $availableactivitytypes[$activity->modname] = $activity->get_module_type_name(true); } asort($availableactivitytypes); $availableactivitytypes = ['all' => get_string('allactivitiesandresources', 'report_progress')] + $availableactivitytypes; // Filter activities by type. if (!empty($activityinclude) && $activityinclude !== 'all') { $activities = array_filter($activities, function($activity) use ($activityinclude) { return $activity->modname === $activityinclude; }); } // The activities are sorted by activity order on course page by default. if ($activityorder === 'alphabetical') { usort($activities, function($a, $b) { return strcmp($a->name, $b->name); }); } return [$availableactivitytypes, $activities]; } } home3/cpr76684/public_html/Aem/cache/classes/helper.php 0000644 00000104642 15152024573 0016471 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Cache helper class * * This file is part of Moodle's cache API, affectionately called MUC. * It contains the components that are requried in order to use caching. * * @package core * @category cache * @copyright 2012 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); /** * The cache helper class. * * The cache helper class provides common functionality to the cache API and is useful to developers within to interact with * the cache API in a general way. * * @package core * @category cache * @copyright 2012 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class cache_helper { /** * Statistics gathered by the cache API during its operation will be used here. * @static * @var array */ protected static $stats = array(); /** * The instance of the cache helper. * @var cache_helper */ protected static $instance; /** * The site identifier used by the cache. * Set the first time get_site_identifier is called. * @var string */ protected static $siteidentifier = null; /** * Returns true if the cache API can be initialised before Moodle has finished initialising itself. * * This check is essential when trying to cache the likes of configuration information. It checks to make sure that the cache * configuration file has been created which allows use to set up caching when ever is required. * * @return bool */ public static function ready_for_early_init() { return cache_config::config_file_exists(); } /** * Returns an instance of the cache_helper. * * This is designed for internal use only and acts as a static store. * @staticvar null $instance * @return cache_helper */ protected static function instance() { if (is_null(self::$instance)) { self::$instance = new cache_helper(); } return self::$instance; } /** * Constructs an instance of the cache_helper class. Again for internal use only. */ protected function __construct() { // Nothing to do here, just making sure you can't get an instance of this. } /** * Used as a data store for initialised definitions. * @var array */ protected $definitions = array(); /** * Used as a data store for initialised cache stores * We use this because we want to avoid establishing multiple instances of a single store. * @var array */ protected $stores = array(); /** * Returns the class for use as a cache loader for the given mode. * * @param int $mode One of cache_store::MODE_ * @return string * @throws coding_exception */ public static function get_class_for_mode($mode) { switch ($mode) { case cache_store::MODE_APPLICATION : return 'cache_application'; case cache_store::MODE_REQUEST : return 'cache_request'; case cache_store::MODE_SESSION : return 'cache_session'; } throw new coding_exception('Unknown cache mode passed. Must be one of cache_store::MODE_*'); } /** * Returns the cache stores to be used with the given definition. * @param cache_definition $definition * @return array */ public static function get_cache_stores(cache_definition $definition) { $instance = cache_config::instance(); $stores = $instance->get_stores_for_definition($definition); $stores = self::initialise_cachestore_instances($stores, $definition); return $stores; } /** * Internal function for initialising an array of stores against a given cache definition. * * @param array $stores * @param cache_definition $definition * @return cache_store[] */ protected static function initialise_cachestore_instances(array $stores, cache_definition $definition) { $return = array(); $factory = cache_factory::instance(); foreach ($stores as $name => $details) { $store = $factory->create_store_from_config($name, $details, $definition); if ($store !== false) { $return[] = $store; } } return $return; } /** * Returns a cache_lock instance suitable for use with the store. * * @param cache_store $store * @return cache_lock_interface */ public static function get_cachelock_for_store(cache_store $store) { $instance = cache_config::instance(); $lockconf = $instance->get_lock_for_store($store->my_name()); $factory = cache_factory::instance(); return $factory->create_lock_instance($lockconf); } /** * Returns an array of plugins without using core methods. * * This function explicitly does NOT use core functions as it will in some circumstances be called before Moodle has * finished initialising. This happens when loading configuration for instance. * * @return string */ public static function early_get_cache_plugins() { global $CFG; $result = array(); $ignored = array('CVS', '_vti_cnf', 'simpletest', 'db', 'yui', 'tests'); $fulldir = $CFG->dirroot.'/cache/stores'; $items = new DirectoryIterator($fulldir); foreach ($items as $item) { if ($item->isDot() or !$item->isDir()) { continue; } $pluginname = $item->getFilename(); if (in_array($pluginname, $ignored)) { continue; } if (!is_valid_plugin_name($pluginname)) { // Better ignore plugins with problematic names here. continue; } $result[$pluginname] = $fulldir.'/'.$pluginname; unset($item); } unset($items); return $result; } /** * Invalidates a given set of keys from a given definition. * * @todo Invalidating by definition should also add to the event cache so that sessions can be invalidated (when required). * * @param string $component * @param string $area * @param array $identifiers * @param array $keys * @return boolean */ public static function invalidate_by_definition($component, $area, array $identifiers = array(), $keys = array()) { $cache = cache::make($component, $area, $identifiers); if (is_array($keys)) { $cache->delete_many($keys); } else if (is_scalar($keys)) { $cache->delete($keys); } else { throw new coding_exception('cache_helper::invalidate_by_definition only accepts $keys as array, or scalar.'); } return true; } /** * Invalidates a given set of keys by means of an event. * * Events cannot determine what identifiers might need to be cleared. Event based purge and invalidation * are only supported on caches without identifiers. * * @param string $event * @param array $keys */ public static function invalidate_by_event($event, array $keys) { $instance = cache_config::instance(); $invalidationeventset = false; $factory = cache_factory::instance(); $inuse = $factory->get_caches_in_use(); $purgetoken = null; foreach ($instance->get_definitions() as $name => $definitionarr) { $definition = cache_definition::load($name, $definitionarr); if ($definition->invalidates_on_event($event)) { // First up check if there is a cache loader for this definition already. // If there is we need to invalidate the keys from there. $definitionkey = $definition->get_component().'/'.$definition->get_area(); if (isset($inuse[$definitionkey])) { $inuse[$definitionkey]->delete_many($keys); } // We should only log events for application and session caches. // Request caches shouldn't have events as all data is lost at the end of the request. // Events should only be logged once of course and likely several definitions are watching so we // track its logging with $invalidationeventset. $logevent = ($invalidationeventset === false && $definition->get_mode() !== cache_store::MODE_REQUEST); if ($logevent) { // Get the event invalidation cache. $cache = cache::make('core', 'eventinvalidation'); // Get any existing invalidated keys for this cache. $data = $cache->get($event); if ($data === false) { // There are none. $data = array(); } // Add our keys to them with the current cache timestamp. if (null === $purgetoken) { $purgetoken = cache::get_purge_token(true); } foreach ($keys as $key) { $data[$key] = $purgetoken; } // Set that data back to the cache. $cache->set($event, $data); // This only needs to occur once. $invalidationeventset = true; } } } } /** * Purges the cache for a specific definition. * * @param string $component * @param string $area * @param array $identifiers * @return bool */ public static function purge_by_definition($component, $area, array $identifiers = array()) { // Create the cache. $cache = cache::make($component, $area, $identifiers); // Initialise, in case of a store. if ($cache instanceof cache_store) { $factory = cache_factory::instance(); $definition = $factory->create_definition($component, $area, null); $cacheddefinition = clone $definition; $cacheddefinition->set_identifiers($identifiers); $cache->initialise($cacheddefinition); } // Purge baby, purge. $cache->purge(); return true; } /** * Purges a cache of all information on a given event. * * Events cannot determine what identifiers might need to be cleared. Event based purge and invalidation * are only supported on caches without identifiers. * * @param string $event */ public static function purge_by_event($event) { $instance = cache_config::instance(); $invalidationeventset = false; $factory = cache_factory::instance(); $inuse = $factory->get_caches_in_use(); $purgetoken = null; foreach ($instance->get_definitions() as $name => $definitionarr) { $definition = cache_definition::load($name, $definitionarr); if ($definition->invalidates_on_event($event)) { // First up check if there is a cache loader for this definition already. // If there is we need to invalidate the keys from there. $definitionkey = $definition->get_component().'/'.$definition->get_area(); if (isset($inuse[$definitionkey])) { $inuse[$definitionkey]->purge(); } else { cache::make($definition->get_component(), $definition->get_area())->purge(); } // We should only log events for application and session caches. // Request caches shouldn't have events as all data is lost at the end of the request. // Events should only be logged once of course and likely several definitions are watching so we // track its logging with $invalidationeventset. $logevent = ($invalidationeventset === false && $definition->get_mode() !== cache_store::MODE_REQUEST); // We need to flag the event in the "Event invalidation" cache if it hasn't already happened. if ($logevent && $invalidationeventset === false) { // Get the event invalidation cache. $cache = cache::make('core', 'eventinvalidation'); // Create a key to invalidate all. if (null === $purgetoken) { $purgetoken = cache::get_purge_token(true); } $data = array( 'purged' => $purgetoken, ); // Set that data back to the cache. $cache->set($event, $data); // This only needs to occur once. $invalidationeventset = true; } } } } /** * Ensure that the stats array is ready to collect information for the given store and definition. * @param string $store * @param string $storeclass * @param string $definition A string that identifies the definition. * @param int $mode One of cache_store::MODE_*. Since 2.9. */ protected static function ensure_ready_for_stats($store, $storeclass, $definition, $mode = cache_store::MODE_APPLICATION) { // This function is performance-sensitive, so exit as quickly as possible // if we do not need to do anything. if (isset(self::$stats[$definition]['stores'][$store])) { return; } if (!array_key_exists($definition, self::$stats)) { self::$stats[$definition] = array( 'mode' => $mode, 'stores' => array( $store => array( 'class' => $storeclass, 'hits' => 0, 'misses' => 0, 'sets' => 0, 'iobytes' => cache_store::IO_BYTES_NOT_SUPPORTED, 'locks' => 0, ) ) ); } else if (!array_key_exists($store, self::$stats[$definition]['stores'])) { self::$stats[$definition]['stores'][$store] = array( 'class' => $storeclass, 'hits' => 0, 'misses' => 0, 'sets' => 0, 'iobytes' => cache_store::IO_BYTES_NOT_SUPPORTED, 'locks' => 0, ); } } /** * Returns a string to describe the definition. * * This method supports the definition as a string due to legacy requirements. * It is backwards compatible when a string is passed but is not accurate. * * @since 2.9 * @param cache_definition|string $definition * @return string */ protected static function get_definition_stat_id_and_mode($definition) { if (!($definition instanceof cache_definition)) { // All core calls to this method have been updated, this is the legacy state. // We'll use application as the default as that is the most common, really this is not accurate of course but // at this point we can only guess and as it only affects calls to cache stat outside of core (of which there should // be none) I think that is fine. debugging('Please update you cache stat calls to pass the definition rather than just its ID.', DEBUG_DEVELOPER); return array((string)$definition, cache_store::MODE_APPLICATION); } return array($definition->get_id(), $definition->get_mode()); } /** * Record a cache hit in the stats for the given store and definition. * * In Moodle 2.9 the $definition argument changed from accepting only a string to accepting a string or a * cache_definition instance. It is preferable to pass a cache definition instance. * * In Moodle 3.9 the first argument changed to also accept a cache_store. * * @internal * @param string|cache_store $store * @param cache_definition $definition You used to be able to pass a string here, however that is deprecated please pass the * actual cache_definition object now. * @param int $hits The number of hits to record (by default 1) * @param int $readbytes Number of bytes read from the cache or cache_store::IO_BYTES_NOT_SUPPORTED */ public static function record_cache_hit($store, $definition, int $hits = 1, int $readbytes = cache_store::IO_BYTES_NOT_SUPPORTED): void { $storeclass = ''; if ($store instanceof cache_store) { $storeclass = get_class($store); $store = $store->my_name(); } list($definitionstr, $mode) = self::get_definition_stat_id_and_mode($definition); self::ensure_ready_for_stats($store, $storeclass, $definitionstr, $mode); self::$stats[$definitionstr]['stores'][$store]['hits'] += $hits; if ($readbytes !== cache_store::IO_BYTES_NOT_SUPPORTED) { if (self::$stats[$definitionstr]['stores'][$store]['iobytes'] === cache_store::IO_BYTES_NOT_SUPPORTED) { self::$stats[$definitionstr]['stores'][$store]['iobytes'] = $readbytes; } else { self::$stats[$definitionstr]['stores'][$store]['iobytes'] += $readbytes; } } } /** * Record a cache miss in the stats for the given store and definition. * * In Moodle 2.9 the $definition argument changed from accepting only a string to accepting a string or a * cache_definition instance. It is preferable to pass a cache definition instance. * * In Moodle 3.9 the first argument changed to also accept a cache_store. * * @internal * @param string|cache_store $store * @param cache_definition $definition You used to be able to pass a string here, however that is deprecated please pass the * actual cache_definition object now. * @param int $misses The number of misses to record (by default 1) */ public static function record_cache_miss($store, $definition, $misses = 1) { $storeclass = ''; if ($store instanceof cache_store) { $storeclass = get_class($store); $store = $store->my_name(); } list($definitionstr, $mode) = self::get_definition_stat_id_and_mode($definition); self::ensure_ready_for_stats($store, $storeclass, $definitionstr, $mode); self::$stats[$definitionstr]['stores'][$store]['misses'] += $misses; } /** * Record a cache set in the stats for the given store and definition. * * In Moodle 2.9 the $definition argument changed from accepting only a string to accepting a string or a * cache_definition instance. It is preferable to pass a cache definition instance. * * In Moodle 3.9 the first argument changed to also accept a cache_store. * * @internal * @param string|cache_store $store * @param cache_definition $definition You used to be able to pass a string here, however that is deprecated please pass the * actual cache_definition object now. * @param int $sets The number of sets to record (by default 1) * @param int $writebytes Number of bytes written to the cache or cache_store::IO_BYTES_NOT_SUPPORTED */ public static function record_cache_set($store, $definition, int $sets = 1, int $writebytes = cache_store::IO_BYTES_NOT_SUPPORTED) { $storeclass = ''; if ($store instanceof cache_store) { $storeclass = get_class($store); $store = $store->my_name(); } list($definitionstr, $mode) = self::get_definition_stat_id_and_mode($definition); self::ensure_ready_for_stats($store, $storeclass, $definitionstr, $mode); self::$stats[$definitionstr]['stores'][$store]['sets'] += $sets; if ($writebytes !== cache_store::IO_BYTES_NOT_SUPPORTED) { if (self::$stats[$definitionstr]['stores'][$store]['iobytes'] === cache_store::IO_BYTES_NOT_SUPPORTED) { self::$stats[$definitionstr]['stores'][$store]['iobytes'] = $writebytes; } else { self::$stats[$definitionstr]['stores'][$store]['iobytes'] += $writebytes; } } } /** * Return the stats collected so far. * @return array */ public static function get_stats() { return self::$stats; } /** * Purge all of the cache stores of all of their data. * * Think twice before calling this method. It will purge **ALL** caches regardless of whether they have been used recently or * anything. This will involve full setup of the cache + the purge operation. On a site using caching heavily this WILL be * painful. * * @param bool $usewriter If set to true the cache_config_writer class is used. This class is special as it avoids * it is still usable when caches have been disabled. * Please use this option only if you really must. It's purpose is to allow the cache to be purged when it would be * otherwise impossible. */ public static function purge_all($usewriter = false) { $factory = cache_factory::instance(); $config = $factory->create_config_instance($usewriter); foreach ($config->get_all_stores() as $store) { self::purge_store($store['name'], $config); } foreach ($factory->get_adhoc_caches_in_use() as $cache) { $cache->purge(); } } /** * Purges a store given its name. * * @param string $storename * @param cache_config $config * @return bool */ public static function purge_store($storename, cache_config $config = null) { if ($config === null) { $config = cache_config::instance(); } $stores = $config->get_all_stores(); if (!array_key_exists($storename, $stores)) { // The store does not exist. return false; } $store = $stores[$storename]; $class = $store['class']; // We check are_requirements_met although we expect is_ready is going to check as well. if (!$class::are_requirements_met()) { return false; } // Found the store: is it ready? /* @var cache_store $instance */ $instance = new $class($store['name'], $store['configuration']); if (!$instance->is_ready()) { unset($instance); return false; } foreach ($config->get_definitions_by_store($storename) as $id => $definition) { $definition = cache_definition::load($id, $definition); $definitioninstance = clone($instance); $definitioninstance->initialise($definition); $definitioninstance->purge(); unset($definitioninstance); } return true; } /** * Purges all of the stores used by a definition. * * Unlike cache_helper::purge_by_definition this purges all of the data from the stores not * just the data relating to the definition. * This function is useful when you must purge a definition that requires setup but you don't * want to set it up. * * @param string $component * @param string $area */ public static function purge_stores_used_by_definition($component, $area) { $factory = cache_factory::instance(); $config = $factory->create_config_instance(); $definition = $factory->create_definition($component, $area); $stores = $config->get_stores_for_definition($definition); foreach ($stores as $store) { self::purge_store($store['name']); } } /** * Returns the translated name of the definition. * * @param cache_definition $definition * @return lang_string */ public static function get_definition_name($definition) { if ($definition instanceof cache_definition) { return $definition->get_name(); } $identifier = 'cachedef_'.clean_param($definition['area'], PARAM_STRINGID); $component = $definition['component']; if ($component === 'core') { $component = 'cache'; } return new lang_string($identifier, $component); } /** * Hashes a descriptive key to make it shorter and still unique. * @param string|int $key * @param cache_definition $definition * @return string */ public static function hash_key($key, cache_definition $definition) { if ($definition->uses_simple_keys()) { if (debugging() && preg_match('#[^a-zA-Z0-9_]#', $key ?? '')) { throw new coding_exception('Cache definition '.$definition->get_id().' requires simple keys. Invalid key provided.', $key); } // We put the key first so that we can be sure the start of the key changes. return (string)$key . '-' . $definition->generate_single_key_prefix(); } $key = $definition->generate_single_key_prefix() . '-' . $key; return sha1($key); } /** * Finds all definitions and updates them within the cache config file. * * @param bool $coreonly If set to true only core definitions will be updated. */ public static function update_definitions($coreonly = false) { global $CFG; // Include locallib. require_once($CFG->dirroot.'/cache/locallib.php'); // First update definitions cache_config_writer::update_definitions($coreonly); // Second reset anything we have already initialised to ensure we're all up to date. cache_factory::reset(); } /** * Update the site identifier stored by the cache API. * * @param string $siteidentifier * @return string The new site identifier. */ public static function update_site_identifier($siteidentifier) { global $CFG; // Include locallib. require_once($CFG->dirroot.'/cache/locallib.php'); $factory = cache_factory::instance(); $factory->updating_started(); $config = $factory->create_config_instance(true); $siteidentifier = $config->update_site_identifier($siteidentifier); $factory->updating_finished(); cache_factory::reset(); return $siteidentifier; } /** * Returns the site identifier. * * @return string */ public static function get_site_identifier() { global $CFG; if (!is_null(self::$siteidentifier)) { return self::$siteidentifier; } // If site identifier hasn't been collected yet attempt to get it from the cache config. $factory = cache_factory::instance(); // If the factory is initialising then we don't want to try to get it from the config or we risk // causing the cache to enter an infinite initialisation loop. if (!$factory->is_initialising()) { $config = $factory->create_config_instance(); self::$siteidentifier = $config->get_site_identifier(); } if (is_null(self::$siteidentifier)) { // If the site identifier is still null then config isn't aware of it yet. // We'll see if the CFG is loaded, and if not we will just use unknown. // It's very important here that we don't use get_config. We don't want an endless cache loop! if (!empty($CFG->siteidentifier)) { self::$siteidentifier = self::update_site_identifier($CFG->siteidentifier); } else { // It's not being recorded in MUC's config and the config data hasn't been loaded yet. // Likely we are initialising. return 'unknown'; } } return self::$siteidentifier; } /** * Returns the site version. * * @return string */ public static function get_site_version() { global $CFG; return (string)$CFG->version; } /** * Runs cron routines for MUC. */ public static function cron() { self::clean_old_session_data(true); } /** * Cleans old session data from cache stores used for session based definitions. * * @param bool $output If set to true output will be given. */ public static function clean_old_session_data($output = false) { global $CFG; if ($output) { mtrace('Cleaning up stale session data from cache stores.'); } $factory = cache_factory::instance(); $config = $factory->create_config_instance(); $definitions = $config->get_definitions(); $purgetime = time() - $CFG->sessiontimeout; foreach ($definitions as $definitionarray) { // We are only interested in session caches. if (!($definitionarray['mode'] & cache_store::MODE_SESSION)) { continue; } $definition = $factory->create_definition($definitionarray['component'], $definitionarray['area']); $stores = $config->get_stores_for_definition($definition); // Turn them into store instances. $stores = self::initialise_cachestore_instances($stores, $definition); // Initialise all of the stores used for that definition. foreach ($stores as $store) { // If the store doesn't support searching we can skip it. if (!($store instanceof cache_is_searchable)) { debugging('Cache stores used for session definitions should ideally be searchable.', DEBUG_DEVELOPER); continue; } // Get all of the keys. $keys = $store->find_by_prefix(cache_session::KEY_PREFIX); $todelete = array(); foreach ($store->get_many($keys) as $key => $value) { if (strpos($key, cache_session::KEY_PREFIX) !== 0 || !is_array($value) || !isset($value['lastaccess'])) { continue; } if ((int)$value['lastaccess'] < $purgetime || true) { $todelete[] = $key; } } if (count($todelete)) { $outcome = (int)$store->delete_many($todelete); if ($output) { $strdef = s($definition->get_id()); $strstore = s($store->my_name()); mtrace("- Removed {$outcome} old {$strdef} sessions from the '{$strstore}' cache store."); } } } } } /** * Returns an array of stores that would meet the requirements for every definition. * * These stores would be 100% suitable to map as defaults for cache modes. * * @return array[] An array of stores, keys are the store names. */ public static function get_stores_suitable_for_mode_default() { $factory = cache_factory::instance(); $config = $factory->create_config_instance(); $requirements = 0; foreach ($config->get_definitions() as $definition) { $definition = cache_definition::load($definition['component'].'/'.$definition['area'], $definition); $requirements = $requirements | $definition->get_requirements_bin(); } $stores = array(); foreach ($config->get_all_stores() as $name => $store) { if (!empty($store['features']) && ($store['features'] & $requirements)) { $stores[$name] = $store; } } return $stores; } /** * Returns stores suitable for use with a given definition. * * @param cache_definition $definition * @return cache_store[] */ public static function get_stores_suitable_for_definition(cache_definition $definition) { $factory = cache_factory::instance(); $stores = array(); if ($factory->is_initialising() || $factory->stores_disabled()) { // No suitable stores here. return $stores; } else { $stores = self::get_cache_stores($definition); // If mappingsonly is set, having 0 stores is ok. if ((count($stores) === 0) && (!$definition->is_for_mappings_only())) { // No suitable stores we found for the definition. We need to come up with a sensible default. // If this has happened we can be sure that the user has mapped custom stores to either the // mode of the definition. The first alternative to try is the system default for the mode. // e.g. the default file store instance for application definitions. $config = $factory->create_config_instance(); foreach ($config->get_stores($definition->get_mode()) as $name => $details) { if (!empty($details['default'])) { $stores[] = $factory->create_store_from_config($name, $details, $definition); break; } } } } return $stores; } /** * Returns an array of warnings from the cache API. * * The warning returned here are for things like conflicting store instance configurations etc. * These get shown on the admin notifications page for example. * * @param array|null $stores An array of stores to get warnings for, or null for all. * @return string[] */ public static function warnings(array $stores = null) { global $CFG; if ($stores === null) { require_once($CFG->dirroot.'/cache/locallib.php'); $stores = core_cache\administration_helper::get_store_instance_summaries(); } $warnings = array(); foreach ($stores as $store) { if (!empty($store['warnings'])) { $warnings = array_merge($warnings, $store['warnings']); } } return $warnings; } } home3/cpr76684/public_html/Aem/admin/tool/usertours/classes/helper.php 0000644 00000045425 15152067066 0021555 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Tour helper. * * @package tool_usertours * @copyright 2016 Andrew Nicols <andrew@nicols.co.uk> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace tool_usertours; use core\output\inplace_editable; use tool_usertours\local\clientside_filter\clientside_filter; defined('MOODLE_INTERNAL') || die(); /** * Tour helper. * * @copyright 2016 Andrew Nicols <andrew@nicols.co.uk> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class helper { /** * @var MOVE_UP */ const MOVE_UP = -1; /** * @var MOVE_DOWN */ const MOVE_DOWN = 1; /** * @var boolean Has it been bootstrapped? */ private static $bootstrapped = false; /** * @var string Regex to check any matching lang string. */ protected const LANG_STRING_REGEX = '|^([a-zA-Z][a-zA-Z0-9\.:/_-]*),([a-zA-Z][a-zA-Z0-9\.:/_-]*)$|'; /** * Get the link to edit the step. * * If no stepid is specified, then a link to create a new step is provided. The $targettype must be specified in this case. * * @param int $tourid The tour that the step belongs to. * @param int $stepid The step ID. * @param int $targettype The type of step. * * @return moodle_url */ public static function get_edit_step_link($tourid, $stepid = null, $targettype = null) { $link = new \moodle_url('/admin/tool/usertours/configure.php'); if ($stepid) { $link->param('action', manager::ACTION_EDITSTEP); $link->param('id', $stepid); } else { $link->param('action', manager::ACTION_NEWSTEP); $link->param('tourid', $tourid); } return $link; } /** * Get the link to move the tour. * * @param int $tourid The tour ID. * @param int $direction The direction to move in * * @return moodle_url */ public static function get_move_tour_link($tourid, $direction = self::MOVE_DOWN) { $link = new \moodle_url('/admin/tool/usertours/configure.php'); $link->param('action', manager::ACTION_MOVETOUR); $link->param('id', $tourid); $link->param('direction', $direction); $link->param('sesskey', sesskey()); return $link; } /** * Get the link to move the step. * * @param int $stepid The step ID. * @param int $direction The direction to move in * * @return moodle_url */ public static function get_move_step_link($stepid, $direction = self::MOVE_DOWN) { $link = new \moodle_url('/admin/tool/usertours/configure.php'); $link->param('action', manager::ACTION_MOVESTEP); $link->param('id', $stepid); $link->param('direction', $direction); $link->param('sesskey', sesskey()); return $link; } /** * Get the link ot create a new step. * * @param int $tourid The ID of the tour to attach this step to. * @param int $targettype The type of target. * * @return moodle_url The required URL. */ public static function get_new_step_link($tourid, $targettype = null) { $link = new \moodle_url('/admin/tool/usertours/configure.php'); $link->param('action', manager::ACTION_NEWSTEP); $link->param('tourid', $tourid); $link->param('targettype', $targettype); return $link; } /** * Get the link used to view the tour. * * @param int $tourid The ID of the tour to display. * @return moodle_url The URL. */ public static function get_view_tour_link($tourid) { return new \moodle_url('/admin/tool/usertours/configure.php', [ 'id' => $tourid, 'action' => manager::ACTION_VIEWTOUR, ]); } /** * Get the link used to reset the tour state for all users. * * @param int $tourid The ID of the tour to display. * @return moodle_url The URL. */ public static function get_reset_tour_for_all_link($tourid) { return new \moodle_url('/admin/tool/usertours/configure.php', [ 'id' => $tourid, 'action' => manager::ACTION_RESETFORALL, 'sesskey' => sesskey(), ]); } /** * Get the link used to edit the tour. * * @param int $tourid The ID of the tour to edit. * @return moodle_url The URL. */ public static function get_edit_tour_link($tourid = null) { $link = new \moodle_url('/admin/tool/usertours/configure.php'); if ($tourid) { $link->param('action', manager::ACTION_EDITTOUR); $link->param('id', $tourid); } else { $link->param('action', manager::ACTION_NEWTOUR); } return $link; } /** * Get the link used to import the tour. * * @return moodle_url The URL. */ public static function get_import_tour_link() { $link = new \moodle_url('/admin/tool/usertours/configure.php', [ 'action' => manager::ACTION_IMPORTTOUR, ]); return $link; } /** * Get the link used to export the tour. * * @param int $tourid The ID of the tour to export. * @return moodle_url The URL. */ public static function get_export_tour_link($tourid) { $link = new \moodle_url('/admin/tool/usertours/configure.php', [ 'action' => manager::ACTION_EXPORTTOUR, 'id' => $tourid, ]); return $link; } /** * Get the link used to duplicate the tour. * * @param int $tourid The ID of the tour to duplicate. * @return moodle_url The URL. */ public static function get_duplicate_tour_link($tourid) { $link = new \moodle_url('/admin/tool/usertours/configure.php', [ 'action' => manager::ACTION_DUPLICATETOUR, 'id' => $tourid, ]); return $link; } /** * Get the link used to delete the tour. * * @param int $tourid The ID of the tour to delete. * @return moodle_url The URL. */ public static function get_delete_tour_link($tourid) { return new \moodle_url('/admin/tool/usertours/configure.php', [ 'id' => $tourid, 'action' => manager::ACTION_DELETETOUR, 'sesskey' => sesskey(), ]); } /** * Get the link for listing tours. * * @return moodle_url The URL. */ public static function get_list_tour_link() { $link = new \moodle_url('/admin/tool/usertours/configure.php'); $link->param('action', manager::ACTION_LISTTOURS); return $link; } /** * Get a filler icon for display in the actions column of a table. * * @param string $url The URL for the icon. * @param string $icon The icon identifier. * @param string $alt The alt text for the icon. * @param string $iconcomponent The icon component. * @param array $options Display options. * @return string */ public static function format_icon_link($url, $icon, $alt, $iconcomponent = 'moodle', $options = array()) { global $OUTPUT; return $OUTPUT->action_icon( $url, new \pix_icon($icon, $alt, $iconcomponent, [ 'title' => $alt, ]), null, $options ); } /** * Get a filler icon for display in the actions column of a table. * * @param array $options Display options. * @return string */ public static function get_filler_icon($options = array()) { global $OUTPUT; return \html_writer::span( $OUTPUT->pix_icon('t/filler', '', 'tool_usertours', $options), 'action-icon' ); } /** * Get the link for deleting steps. * * @param int $stepid The ID of the step to display. * @return moodle_url The URL. */ public static function get_delete_step_link($stepid) { return new \moodle_url('/admin/tool/usertours/configure.php', [ 'action' => manager::ACTION_DELETESTEP, 'id' => $stepid, 'sesskey' => sesskey(), ]); } /** * Render the inplace editable used to edit the tour name. * * @param tour $tour The tour to edit. * @return inplace_editable */ public static function render_tourname_inplace_editable(tour $tour): inplace_editable { $name = format_text(static::get_string_from_input($tour->get_name()), FORMAT_HTML); return new inplace_editable( 'tool_usertours', 'tourname', $tour->get_id(), true, \html_writer::link( $tour->get_view_link(), $name ), $tour->get_name() ); } /** * Render the inplace editable used to edit the tour description. * * @param tour $tour The tour to edit. * @return inplace_editable */ public static function render_tourdescription_inplace_editable(tour $tour): inplace_editable { $description = format_text(static::get_string_from_input($tour->get_description()), FORMAT_HTML); return new inplace_editable( 'tool_usertours', 'tourdescription', $tour->get_id(), true, $description, $tour->get_description() ); } /** * Render the inplace editable used to edit the tour enable state. * * @param tour $tour The tour to edit. * @return inplace_editable */ public static function render_tourenabled_inplace_editable(tour $tour): inplace_editable { global $OUTPUT; if ($tour->is_enabled()) { $icon = 't/hide'; $alt = get_string('disable'); $value = 1; } else { $icon = 't/show'; $alt = get_string('enable'); $value = 0; } $editable = new inplace_editable( 'tool_usertours', 'tourenabled', $tour->get_id(), true, $OUTPUT->pix_icon($icon, $alt, 'moodle', [ 'title' => $alt, ]), $value ); $editable->set_type_toggle(); return $editable; } /** * Render the inplace editable used to edit the step name. * * @param step $step The step to edit. * @return inplace_editable */ public static function render_stepname_inplace_editable(step $step): inplace_editable { $title = format_text(static::get_string_from_input($step->get_title()), FORMAT_HTML); return new inplace_editable( 'tool_usertours', 'stepname', $step->get_id(), true, \html_writer::link( $step->get_edit_link(), $title ), $step->get_title() ); } /** * Get all of the tours. * * @return stdClass[] */ public static function get_tours() { global $DB; $tours = $DB->get_records('tool_usertours_tours', array(), 'sortorder ASC'); $return = []; foreach ($tours as $tour) { $return[$tour->id] = tour::load_from_record($tour); } return $return; } /** * Get the specified tour. * * @param int $tourid The tour that the step belongs to. * @return tour */ public static function get_tour($tourid) { return tour::instance($tourid); } /** * Fetch the tour with the specified sortorder. * * @param int $sortorder The sortorder of the tour. * @return tour */ public static function get_tour_from_sortorder($sortorder) { global $DB; $tour = $DB->get_record('tool_usertours_tours', array('sortorder' => $sortorder)); return tour::load_from_record($tour); } /** * Return the count of all tours. * * @return int */ public static function count_tours() { global $DB; return $DB->count_records('tool_usertours_tours'); } /** * Reset the sortorder for all tours. */ public static function reset_tour_sortorder() { global $DB; $tours = $DB->get_records('tool_usertours_tours', null, 'sortorder ASC, pathmatch DESC', 'id, sortorder'); $index = 0; foreach ($tours as $tour) { if ($tour->sortorder != $index) { $DB->set_field('tool_usertours_tours', 'sortorder', $index, array('id' => $tour->id)); } $index++; } // Notify the cache that a tour has changed. // Tours are only stored in the cache if there are steps. // If there step count has changed for some reason, this will change the potential cache results. cache::notify_tour_change(); } /** * Get all of the steps in the tour. * * @param int $tourid The tour that the step belongs to. * @return step[] */ public static function get_steps($tourid) { $steps = cache::get_stepdata($tourid); $return = []; foreach ($steps as $step) { $return[$step->id] = step::load_from_record($step); } return $return; } /** * Fetch the specified step. * * @param int $stepid The id of the step to fetch. * @return step */ public static function get_step($stepid) { return step::instance($stepid); } /** * Fetch the step with the specified sortorder. * * @param int $tourid The tour that the step belongs to. * @param int $sortorder The sortorder of the step. * @return step */ public static function get_step_from_sortorder($tourid, $sortorder) { global $DB; $step = $DB->get_record('tool_usertours_steps', array('tourid' => $tourid, 'sortorder' => $sortorder)); return step::load_from_record($step); } /** * Handle addition of the tour into the current page. */ public static function bootstrap() { global $PAGE; if (!isloggedin() || isguestuser()) { return; } if (in_array($PAGE->pagelayout, ['maintenance', 'print', 'redirect'])) { // Do not try to show user tours inside iframe, in maintenance mode, // when printing, or during redirects. return; } if (self::$bootstrapped) { return; } self::$bootstrapped = true; $tours = manager::get_current_tours(); if ($tours) { $filters = static::get_all_clientside_filters(); $tourdetails = array_map(function($tour) use ($filters) { return [ 'tourId' => $tour->get_id(), 'startTour' => $tour->should_show_for_user(), 'filtervalues' => $tour->get_client_filter_values($filters), ]; }, $tours); $filternames = []; foreach ($filters as $filter) { $filternames[] = $filter::get_filter_name(); } $PAGE->requires->js_call_amd('tool_usertours/usertours', 'init', [ $tourdetails, $filternames, ]); } } /** * Get a list of all possible filters. * * @return array */ public static function get_all_filters() { $filters = \core_component::get_component_classes_in_namespace('tool_usertours', 'local\filter'); $filters = array_keys($filters); $filters = array_filter($filters, function($filterclass) { $rc = new \ReflectionClass($filterclass); return $rc->isInstantiable(); }); $filters = array_merge($filters, static::get_all_clientside_filters()); return $filters; } /** * Get a list of all clientside filters. * * @return array */ public static function get_all_clientside_filters() { $filters = \core_component::get_component_classes_in_namespace('tool_usertours', 'local\clientside_filter'); $filters = array_keys($filters); $filters = array_filter($filters, function($filterclass) { $rc = new \ReflectionClass($filterclass); return $rc->isInstantiable(); }); return $filters; } /** * Attempt to fetch any matching langstring if the content is in the * format identifier,component. * * @param string $content Step's content or Tour's name or Tour's description * @return string Processed content, any langstring will be converted to translated text */ public static function get_string_from_input(string $content): string { $content = trim($content); if (preg_match(static::LANG_STRING_REGEX, $content, $matches)) { if ($matches[2] === 'moodle') { $matches[2] = 'core'; } if (get_string_manager()->string_exists($matches[1], $matches[2])) { $content = get_string($matches[1], $matches[2]); } } return $content; } /** * Check if the given string contains any matching langstring. * * @param string $string * @return bool */ public static function is_language_string_from_input(string $string): bool { return preg_match(static::LANG_STRING_REGEX, $string) == true; } } home3/cpr76684/public_html/Aem/question/engine/upgrade/tests/helper.php 0000644 00000011121 15152067233 0021663 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * This file contains test helper code for testing the upgrade to the new * question engine. The actual tests are organised by question type in files * like question/type/truefalse/tests/upgradelibnewqe_test.php. * * @package moodlecore * @subpackage questionengine * @copyright 2009 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); global $CFG; require_once(__DIR__ . '/../upgradelib.php'); /** * Subclass of question_engine_attempt_upgrader to help with testing. * * @copyright 2009 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class test_question_engine_attempt_upgrader extends question_engine_attempt_upgrader { public function prevent_timeout() { } public function __construct($loader, $logger) { $this->questionloader = $loader; $this->logger = $logger; } } /** * Subclass of question_engine_upgrade_question_loader for unit testing. * * @copyright 2009 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class test_question_engine_upgrade_question_loader extends question_engine_upgrade_question_loader { public function put_question_in_cache($question) { $this->cache[$question->id] = $question; } public function load_question($questionid, $quizid) { global $CFG; if (isset($this->cache[$questionid])) { return $this->cache[$questionid]; } return null; } public function put_dataset_in_cache($questionid, $selecteditem, $dataset) { $this->datasetcache[$questionid][$selecteditem] = $dataset; } public function load_dataset($questionid, $selecteditem) { global $DB; if (isset($this->datasetcache[$questionid][$selecteditem])) { return $this->datasetcache[$questionid][$selecteditem]; } throw new coding_exception('Test dataset not loaded.'); } } /** * Base class for tests that thest the upgrade of one particular attempt and * one question. * * @copyright 2009 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ abstract class question_attempt_upgrader_test_base extends advanced_testcase { protected $updater; protected $loader; protected function setUp(): void { parent::setUp(); $logger = new dummy_question_engine_assumption_logger(); $this->loader = new test_question_engine_upgrade_question_loader($logger); $this->updater = new test_question_engine_attempt_upgrader($this->loader, $logger); } protected function tearDown(): void { $this->updater = null; parent::tearDown(); } /** * Clear text, bringing independence of html2text results * * Some tests performing text comparisons of converted text are too much * dependent of the behavior of the html2text library. This function is * aimed to reduce such dependencies that should not affect the results * of these question attempt upgrade tests. */ protected function clear_html2text_dependencies($qa) { // Cleaning all whitespace should be enough to ignore any html2text dependency if (property_exists($qa, 'responsesummary')) { $qa->responsesummary = preg_replace('/\s/', '', $qa->responsesummary); } if (property_exists($qa, 'questionsummary')) { $qa->questionsummary = preg_replace('/\s/', '', $qa->questionsummary); } } /** * Compare two qas, ignoring inessential differences. * @param object $expectedqa the expected qa. * @param object $qa the actual qa. */ protected function compare_qas($expectedqa, $qa) { $this->clear_html2text_dependencies($expectedqa); $this->clear_html2text_dependencies($qa); $this->assertEquals($expectedqa, $qa); } } home3/cpr76684/public_html/Aem/course/classes/management/helper.php 0000644 00000122040 15152126210 0021021 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Course and category management helper class. * * @package core_course * @copyright 2013 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_course\management; defined('MOODLE_INTERNAL') || die; require_once($CFG->dirroot . '/course/lib.php'); /** * Course and category management interface helper class. * * This class provides methods useful to the course and category management interfaces. * Many of the methods on this class are static and serve one of two purposes. * 1. encapsulate functionality in an effort to ensure minimal changes between the different * methods of interaction. Specifically browser, AJAX and webservice. * 2. abstract logic for acquiring actions away from output so that renderers may use them without * having to include any logic or capability checks. * * @package core_course * @copyright 2013 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class helper { /** * The expanded category structure if its already being loaded from the cache. * @var null|array */ protected static $expandedcategories = null; /** * Returns course details in an array ready to be printed. * * @global \moodle_database $DB * @param \core_course_list_element $course * @return array */ public static function get_course_detail_array(\core_course_list_element $course) { global $DB; $canaccess = $course->can_access(); $format = \course_get_format($course->id); $modinfo = \get_fast_modinfo($course->id); $modules = $modinfo->get_used_module_names(); $sections = array(); if ($format->uses_sections()) { foreach ($modinfo->get_section_info_all() as $section) { if ($section->uservisible) { $sections[] = $format->get_section_name($section); } } } $category = \core_course_category::get($course->category); $categoryurl = new \moodle_url('/course/management.php', array('categoryid' => $course->category)); $categoryname = $category->get_formatted_name(); $details = array( 'fullname' => array( 'key' => \get_string('fullname'), 'value' => $course->get_formatted_fullname() ), 'shortname' => array( 'key' => \get_string('shortname'), 'value' => $course->get_formatted_shortname() ), 'idnumber' => array( 'key' => \get_string('idnumber'), 'value' => s($course->idnumber) ), 'category' => array( 'key' => \get_string('category'), 'value' => \html_writer::link($categoryurl, $categoryname) ) ); if (has_capability('moodle/site:accessallgroups', $course->get_context())) { $groups = \groups_get_course_data($course->id); $details += array( 'groupings' => array( 'key' => \get_string('groupings', 'group'), 'value' => count($groups->groupings) ), 'groups' => array( 'key' => \get_string('groups'), 'value' => count($groups->groups) ) ); } if ($canaccess) { $names = \role_get_names($course->get_context()); $sql = 'SELECT ra.roleid, COUNT(ra.id) AS rolecount FROM {role_assignments} ra WHERE ra.contextid = :contextid GROUP BY ra.roleid'; $rolecounts = $DB->get_records_sql($sql, array('contextid' => $course->get_context()->id)); $roledetails = array(); foreach ($rolecounts as $result) { $a = new \stdClass; $a->role = $names[$result->roleid]->localname; $a->count = $result->rolecount; $roledetails[] = \get_string('assignedrolecount', 'moodle', $a); } $details['roleassignments'] = array( 'key' => \get_string('roleassignments'), 'value' => join('<br />', $roledetails) ); } if ($course->can_review_enrolments()) { $enrolmentlines = array(); $instances = \enrol_get_instances($course->id, true); $plugins = \enrol_get_plugins(true); foreach ($instances as $instance) { if (!isset($plugins[$instance->enrol])) { // Weird. continue; } $plugin = $plugins[$instance->enrol]; $enrolmentlines[] = $plugin->get_instance_name($instance); } $details['enrolmentmethods'] = array( 'key' => \get_string('enrolmentmethods'), 'value' => join('<br />', $enrolmentlines) ); } if ($canaccess) { $details['format'] = array( 'key' => \get_string('format'), 'value' => \course_get_format($course)->get_format_name() ); $details['sections'] = array( 'key' => \get_string('sections'), 'value' => join('<br />', $sections) ); $details['modulesused'] = array( 'key' => \get_string('modulesused'), 'value' => join('<br />', $modules) ); } return $details; } /** * Returns an array of actions that can be performed upon a category being shown in a list. * * @param \core_course_category $category * @return array */ public static function get_category_listitem_actions(\core_course_category $category) { global $CFG; $manageurl = new \moodle_url('/course/management.php', array('categoryid' => $category->id)); $baseurl = new \moodle_url($manageurl, array('sesskey' => \sesskey())); $actions = array(); // View link. $actions['view'] = [ 'url' => new \moodle_url('/course/index.php', ['categoryid' => $category->id]), 'icon' => null, 'string' => get_string('view') ]; // Edit. if ($category->can_edit()) { $actions['edit'] = array( 'url' => new \moodle_url('/course/editcategory.php', array('id' => $category->id)), 'icon' => new \pix_icon('t/edit', new \lang_string('edit')), 'string' => new \lang_string('edit') ); } // Show/Hide. if ($category->can_change_visibility()) { // We always show both icons and then just toggle the display of the invalid option with CSS. $actions['hide'] = array( 'url' => new \moodle_url($baseurl, array('action' => 'hidecategory')), 'icon' => new \pix_icon('t/hide', new \lang_string('hide')), 'string' => new \lang_string('hide') ); $actions['show'] = array( 'url' => new \moodle_url($baseurl, array('action' => 'showcategory')), 'icon' => new \pix_icon('t/show', new \lang_string('show')), 'string' => new \lang_string('show') ); } // Move up/down. if ($category->can_change_sortorder()) { $actions['moveup'] = array( 'url' => new \moodle_url($baseurl, array('action' => 'movecategoryup')), 'icon' => new \pix_icon('t/up', new \lang_string('moveup')), 'string' => new \lang_string('moveup') ); $actions['movedown'] = array( 'url' => new \moodle_url($baseurl, array('action' => 'movecategorydown')), 'icon' => new \pix_icon('t/down', new \lang_string('movedown')), 'string' => new \lang_string('movedown') ); } if ($category->can_create_subcategory()) { $actions['createnewsubcategory'] = array( 'url' => new \moodle_url('/course/editcategory.php', array('parent' => $category->id)), 'icon' => new \pix_icon('i/withsubcat', new \lang_string('createnewsubcategory')), 'string' => new \lang_string('createnewsubcategory') ); } // Resort. if ($category->can_resort_subcategories() && $category->has_children()) { $actions['resortbyname'] = array( 'url' => new \moodle_url($baseurl, array('action' => 'resortcategories', 'resort' => 'name')), 'icon' => new \pix_icon('t/sort', new \lang_string('sort')), 'string' => new \lang_string('resortsubcategoriesby', 'moodle' , get_string('categoryname')) ); $actions['resortbynamedesc'] = array( 'url' => new \moodle_url($baseurl, array('action' => 'resortcategories', 'resort' => 'namedesc')), 'icon' => new \pix_icon('t/sort', new \lang_string('sort')), 'string' => new \lang_string('resortsubcategoriesbyreverse', 'moodle', get_string('categoryname')) ); $actions['resortbyidnumber'] = array( 'url' => new \moodle_url($baseurl, array('action' => 'resortcategories', 'resort' => 'idnumber')), 'icon' => new \pix_icon('t/sort', new \lang_string('sort')), 'string' => new \lang_string('resortsubcategoriesby', 'moodle', get_string('idnumbercoursecategory')) ); $actions['resortbyidnumberdesc'] = array( 'url' => new \moodle_url($baseurl, array('action' => 'resortcategories', 'resort' => 'idnumberdesc')), 'icon' => new \pix_icon('t/sort', new \lang_string('sort')), 'string' => new \lang_string('resortsubcategoriesbyreverse', 'moodle', get_string('idnumbercoursecategory')) ); } // Delete. if (!empty($category->move_content_targets_list()) || $category->can_delete_full()) { $actions['delete'] = array( 'url' => new \moodle_url($baseurl, array('action' => 'deletecategory')), 'icon' => new \pix_icon('t/delete', new \lang_string('delete')), 'string' => new \lang_string('delete') ); } // Permissions. if ($category->can_review_permissions()) { $actions['permissions'] = array( 'url' => new \moodle_url('/admin/roles/permissions.php', ['contextid' => $category->get_context()->id]), 'icon' => new \pix_icon('i/permissions', new \lang_string('permissions', 'role')), 'string' => new \lang_string('permissions', 'role') ); } // Context locking. if (!empty($CFG->contextlocking) && has_capability('moodle/site:managecontextlocks', $category->get_context())) { $parentcontext = $category->get_context()->get_parent_context(); if (empty($parentcontext) || !$parentcontext->locked) { if ($category->get_context()->locked) { $lockicon = 'i/unlock'; $lockstring = get_string('managecontextunlock', 'admin'); } else { $lockicon = 'i/lock'; $lockstring = get_string('managecontextlock', 'admin'); } $actions['managecontextlock'] = [ 'url' => new \moodle_url('/admin/lock.php', [ 'id' => $category->get_context()->id, 'returnurl' => $manageurl->out_as_local_url(false), ]), 'icon' => new \pix_icon($lockicon, $lockstring), 'string' => $lockstring, ]; } } // Cohorts. if ($category->can_review_cohorts()) { $actions['cohorts'] = array( 'url' => new \moodle_url('/cohort/index.php', array('contextid' => $category->get_context()->id)), 'icon' => new \pix_icon('t/cohort', new \lang_string('cohorts', 'cohort')), 'string' => new \lang_string('cohorts', 'cohort') ); } // Filters. if ($category->can_review_filters()) { $actions['filters'] = array( 'url' => new \moodle_url('/filter/manage.php', array('contextid' => $category->get_context()->id, 'return' => 'management')), 'icon' => new \pix_icon('i/filter', new \lang_string('filters', 'admin')), 'string' => new \lang_string('filters', 'admin') ); } if ($category->can_restore_courses_into()) { $actions['restore'] = array( 'url' => new \moodle_url('/backup/restorefile.php', array('contextid' => $category->get_context()->id)), 'icon' => new \pix_icon('i/restore', new \lang_string('restorecourse', 'admin')), 'string' => new \lang_string('restorecourse', 'admin') ); } // Recyclebyn. if (\tool_recyclebin\category_bin::is_enabled()) { $categorybin = new \tool_recyclebin\category_bin($category->id); if ($categorybin->can_view()) { $autohide = get_config('tool_recyclebin', 'autohide'); if ($autohide) { $items = $categorybin->get_items(); } else { $items = []; } if (!$autohide || !empty($items)) { $pluginname = get_string('pluginname', 'tool_recyclebin'); $actions['recyclebin'] = [ 'url' => new \moodle_url('/admin/tool/recyclebin/index.php', ['contextid' => $category->get_context()->id]), 'icon' => new \pix_icon('trash', $pluginname, 'tool_recyclebin'), 'string' => $pluginname ]; } } } // Content bank. if ($category->has_contentbank()) { $url = new \moodle_url('/contentbank/index.php', ['contextid' => $category->get_context()->id]); $actions['contentbank'] = [ 'url' => $url, 'icon' => new \pix_icon('i/contentbank', ''), 'string' => get_string('contentbank') ]; } return $actions; } /** * Returns an array of actions for a course listitem. * * @param \core_course_category $category * @param \core_course_list_element $course * @return array */ public static function get_course_listitem_actions(\core_course_category $category, \core_course_list_element $course) { $baseurl = new \moodle_url( '/course/management.php', array('courseid' => $course->id, 'categoryid' => $course->category, 'sesskey' => \sesskey()) ); $actions = array(); // Edit. if ($course->can_edit()) { $actions[] = array( 'url' => new \moodle_url('/course/edit.php', array('id' => $course->id, 'returnto' => 'catmanage')), 'icon' => new \pix_icon('t/edit', \get_string('edit')), 'attributes' => array('class' => 'action-edit') ); } // Copy. if (self::can_copy_course($course->id)) { $actions[] = array( 'url' => new \moodle_url('/backup/copy.php', array('id' => $course->id, 'returnto' => 'catmanage')), 'icon' => new \pix_icon('t/copy', \get_string('copycourse')), 'attributes' => array('class' => 'action-copy') ); } // Delete. if ($course->can_delete()) { $actions[] = array( 'url' => new \moodle_url('/course/delete.php', array('id' => $course->id)), 'icon' => new \pix_icon('t/delete', \get_string('delete')), 'attributes' => array('class' => 'action-delete') ); } // Show/Hide. if ($course->can_change_visibility()) { $actions[] = array( 'url' => new \moodle_url($baseurl, array('action' => 'hidecourse')), 'icon' => new \pix_icon('t/hide', \get_string('hide')), 'attributes' => array('data-action' => 'hide', 'class' => 'action-hide') ); $actions[] = array( 'url' => new \moodle_url($baseurl, array('action' => 'showcourse')), 'icon' => new \pix_icon('t/show', \get_string('show')), 'attributes' => array('data-action' => 'show', 'class' => 'action-show') ); } // Move up/down. if ($category->can_resort_courses()) { $actions[] = array( 'url' => new \moodle_url($baseurl, array('action' => 'movecourseup')), 'icon' => new \pix_icon('t/up', \get_string('moveup')), 'attributes' => array('data-action' => 'moveup', 'class' => 'action-moveup') ); $actions[] = array( 'url' => new \moodle_url($baseurl, array('action' => 'movecoursedown')), 'icon' => new \pix_icon('t/down', \get_string('movedown')), 'attributes' => array('data-action' => 'movedown', 'class' => 'action-movedown') ); } return $actions; } /** * Returns an array of actions that can be performed on the course being displayed. * * @param \core_course_list_element $course * @return array */ public static function get_course_detail_actions(\core_course_list_element $course) { $params = array('courseid' => $course->id, 'categoryid' => $course->category, 'sesskey' => \sesskey()); $baseurl = new \moodle_url('/course/management.php', $params); $actions = array(); // View. $actions['view'] = array( 'url' => new \moodle_url('/course/view.php', array('id' => $course->id)), 'string' => \get_string('view') ); // Edit. if ($course->can_edit()) { $actions['edit'] = array( 'url' => new \moodle_url('/course/edit.php', array('id' => $course->id)), 'string' => \get_string('edit') ); } // Permissions. if ($course->can_review_enrolments()) { $actions['enrolledusers'] = array( 'url' => new \moodle_url('/user/index.php', array('id' => $course->id)), 'string' => \get_string('enrolledusers', 'enrol') ); } // Delete. if ($course->can_delete()) { $actions['delete'] = array( 'url' => new \moodle_url('/course/delete.php', array('id' => $course->id)), 'string' => \get_string('delete') ); } // Show/Hide. if ($course->can_change_visibility()) { if ($course->visible) { $actions['hide'] = array( 'url' => new \moodle_url($baseurl, array('action' => 'hidecourse')), 'string' => \get_string('hide') ); } else { $actions['show'] = array( 'url' => new \moodle_url($baseurl, array('action' => 'showcourse')), 'string' => \get_string('show') ); } } // Backup. if ($course->can_backup()) { $actions['backup'] = array( 'url' => new \moodle_url('/backup/backup.php', array('id' => $course->id)), 'string' => \get_string('backup') ); } // Restore. if ($course->can_restore()) { $actions['restore'] = array( 'url' => new \moodle_url('/backup/restorefile.php', array('contextid' => $course->get_context()->id)), 'string' => \get_string('restore') ); } return $actions; } /** * Resorts the courses within a category moving the given course up by one. * * @param \core_course_list_element $course * @param \core_course_category $category * @return bool * @throws \moodle_exception */ public static function action_course_change_sortorder_up_one(\core_course_list_element $course, \core_course_category $category) { if (!$category->can_resort_courses()) { throw new \moodle_exception('permissiondenied', 'error', '', null, 'core_course_category::can_resort'); } return \course_change_sortorder_by_one($course, true); } /** * Resorts the courses within a category moving the given course down by one. * * @param \core_course_list_element $course * @param \core_course_category $category * @return bool * @throws \moodle_exception */ public static function action_course_change_sortorder_down_one(\core_course_list_element $course, \core_course_category $category) { if (!$category->can_resort_courses()) { throw new \moodle_exception('permissiondenied', 'error', '', null, 'core_course_category::can_resort'); } return \course_change_sortorder_by_one($course, false); } /** * Resorts the courses within a category moving the given course up by one. * * @global \moodle_database $DB * @param int|\stdClass $courserecordorid * @return bool */ public static function action_course_change_sortorder_up_one_by_record($courserecordorid) { if (is_int($courserecordorid)) { $courserecordorid = get_course($courserecordorid); } $course = new \core_course_list_element($courserecordorid); $category = \core_course_category::get($course->category); return self::action_course_change_sortorder_up_one($course, $category); } /** * Resorts the courses within a category moving the given course down by one. * * @global \moodle_database $DB * @param int|\stdClass $courserecordorid * @return bool */ public static function action_course_change_sortorder_down_one_by_record($courserecordorid) { if (is_int($courserecordorid)) { $courserecordorid = get_course($courserecordorid); } $course = new \core_course_list_element($courserecordorid); $category = \core_course_category::get($course->category); return self::action_course_change_sortorder_down_one($course, $category); } /** * Changes the sort order so that the first course appears after the second course. * * @param int|\stdClass $courserecordorid * @param int $moveaftercourseid * @return bool * @throws \moodle_exception */ public static function action_course_change_sortorder_after_course($courserecordorid, $moveaftercourseid) { $course = \get_course($courserecordorid); $category = \core_course_category::get($course->category); if (!$category->can_resort_courses()) { $url = '/course/management.php?categoryid='.$course->category; throw new \moodle_exception('nopermissions', 'error', $url, \get_string('resortcourses', 'moodle')); } return \course_change_sortorder_after_course($course, $moveaftercourseid); } /** * Makes a course visible given a \core_course_list_element object. * * @param \core_course_list_element $course * @return bool * @throws \moodle_exception */ public static function action_course_show(\core_course_list_element $course) { if (!$course->can_change_visibility()) { throw new \moodle_exception('permissiondenied', 'error', '', null, 'core_course_list_element::can_change_visbility'); } return course_change_visibility($course->id, true); } /** * Makes a course hidden given a \core_course_list_element object. * * @param \core_course_list_element $course * @return bool * @throws \moodle_exception */ public static function action_course_hide(\core_course_list_element $course) { if (!$course->can_change_visibility()) { throw new \moodle_exception('permissiondenied', 'error', '', null, 'core_course_list_element::can_change_visbility'); } return course_change_visibility($course->id, false); } /** * Makes a course visible given a course id or a database record. * * @global \moodle_database $DB * @param int|\stdClass $courserecordorid * @return bool */ public static function action_course_show_by_record($courserecordorid) { if (is_int($courserecordorid)) { $courserecordorid = get_course($courserecordorid); } $course = new \core_course_list_element($courserecordorid); return self::action_course_show($course); } /** * Makes a course hidden given a course id or a database record. * * @global \moodle_database $DB * @param int|\stdClass $courserecordorid * @return bool */ public static function action_course_hide_by_record($courserecordorid) { if (is_int($courserecordorid)) { $courserecordorid = get_course($courserecordorid); } $course = new \core_course_list_element($courserecordorid); return self::action_course_hide($course); } /** * Resort a categories subcategories shifting the given category up one. * * @param \core_course_category $category * @return bool * @throws \moodle_exception */ public static function action_category_change_sortorder_up_one(\core_course_category $category) { if (!$category->can_change_sortorder()) { throw new \moodle_exception('permissiondenied', 'error', '', null, 'core_course_category::can_change_sortorder'); } return $category->change_sortorder_by_one(true); } /** * Resort a categories subcategories shifting the given category down one. * * @param \core_course_category $category * @return bool * @throws \moodle_exception */ public static function action_category_change_sortorder_down_one(\core_course_category $category) { if (!$category->can_change_sortorder()) { throw new \moodle_exception('permissiondenied', 'error', '', null, 'core_course_category::can_change_sortorder'); } return $category->change_sortorder_by_one(false); } /** * Resort a categories subcategories shifting the given category up one. * * @param int $categoryid * @return bool */ public static function action_category_change_sortorder_up_one_by_id($categoryid) { $category = \core_course_category::get($categoryid); return self::action_category_change_sortorder_up_one($category); } /** * Resort a categories subcategories shifting the given category down one. * * @param int $categoryid * @return bool */ public static function action_category_change_sortorder_down_one_by_id($categoryid) { $category = \core_course_category::get($categoryid); return self::action_category_change_sortorder_down_one($category); } /** * Makes a category hidden given a core_course_category object. * * @param \core_course_category $category * @return bool * @throws \moodle_exception */ public static function action_category_hide(\core_course_category $category) { if (!$category->can_change_visibility()) { throw new \moodle_exception('permissiondenied', 'error', '', null, 'core_course_category::can_change_visbility'); } $category->hide(); return true; } /** * Makes a category visible given a core_course_category object. * * @param \core_course_category $category * @return bool * @throws \moodle_exception */ public static function action_category_show(\core_course_category $category) { if (!$category->can_change_visibility()) { throw new \moodle_exception('permissiondenied', 'error', '', null, 'core_course_category::can_change_visbility'); } $category->show(); return true; } /** * Makes a category visible given a course category id or database record. * * @param int|\stdClass $categoryid * @return bool */ public static function action_category_show_by_id($categoryid) { return self::action_category_show(\core_course_category::get($categoryid)); } /** * Makes a category hidden given a course category id or database record. * * @param int|\stdClass $categoryid * @return bool */ public static function action_category_hide_by_id($categoryid) { return self::action_category_hide(\core_course_category::get($categoryid)); } /** * Resorts the sub categories of the given category. * * @param \core_course_category $category * @param string $sort One of idnumber or name. * @param bool $cleanup If true cleanup will be done, if false you will need to do it manually later. * @return bool * @throws \moodle_exception */ public static function action_category_resort_subcategories(\core_course_category $category, $sort, $cleanup = true) { if (!$category->can_resort_subcategories()) { throw new \moodle_exception('permissiondenied', 'error', '', null, 'core_course_category::can_resort'); } return $category->resort_subcategories($sort, $cleanup); } /** * Resorts the courses within the given category. * * @param \core_course_category $category * @param string $sort One of fullname, shortname or idnumber * @param bool $cleanup If true cleanup will be done, if false you will need to do it manually later. * @return bool * @throws \moodle_exception */ public static function action_category_resort_courses(\core_course_category $category, $sort, $cleanup = true) { if (!$category->can_resort_courses()) { throw new \moodle_exception('permissiondenied', 'error', '', null, 'core_course_category::can_resort'); } return $category->resort_courses($sort, $cleanup); } /** * Moves courses out of one category and into a new category. * * @param \core_course_category $oldcategory The category we are moving courses out of. * @param \core_course_category $newcategory The category we are moving courses into. * @param array $courseids The ID's of the courses we want to move. * @return bool True on success. * @throws \moodle_exception */ public static function action_category_move_courses_into(\core_course_category $oldcategory, \core_course_category $newcategory, array $courseids) { global $DB; list($where, $params) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED); $params['categoryid'] = $oldcategory->id; $sql = "SELECT c.id FROM {course} c WHERE c.id {$where} AND c.category <> :categoryid"; if ($DB->record_exists_sql($sql, $params)) { // Likely being tinkered with. throw new \moodle_exception('coursedoesnotbelongtocategory'); } // All courses are currently within the old category. return self::move_courses_into_category($newcategory, $courseids); } /** * Returns the view modes for the management interface. * @return array */ public static function get_management_viewmodes() { return array( 'combined' => new \lang_string('categoriesandcourses'), 'categories' => new \lang_string('categories'), 'courses' => new \lang_string('courses') ); } /** * Search for courses with matching params. * * Please note that only one of search, blocklist, or modulelist can be specified at a time. * Specifying more than one will result in only the first being used. * * @param string $search Words to search for. We search fullname, shortname, idnumber and summary. * @param int $blocklist The ID of a block, courses will only be returned if they use this block. * @param string $modulelist The name of a module (relates to database table name). Only courses containing this module * will be returned. * @param int $page The page number to display, starting at 0. * @param int $perpage The number of courses to display per page. * @return array */ public static function search_courses($search, $blocklist, $modulelist, $page = 0, $perpage = null) { global $CFG; if ($perpage === null) { $perpage = $CFG->coursesperpage; } $searchcriteria = array(); if (!empty($search)) { $searchcriteria = array('search' => $search); } else if (!empty($blocklist)) { $searchcriteria = array('blocklist' => $blocklist); } else if (!empty($modulelist)) { $searchcriteria = array('modulelist' => $modulelist); } $topcat = \core_course_category::top(); $courses = $topcat->search_courses($searchcriteria, array( 'recursive' => true, 'offset' => $page * $perpage, 'limit' => $perpage, 'sort' => array('fullname' => 1) )); $totalcount = $topcat->search_courses_count($searchcriteria, array('recursive' => true)); return array($courses, \count($courses), $totalcount); } /** * Moves one or more courses out of the category they are currently in and into a new category. * * This function works much the same way as action_category_move_courses_into however it allows courses from multiple * categories to be moved into a single category. * * @param int|\core_course_category $categoryorid The category to move them into. * @param array|int $courseids An array of course id's or optionally just a single course id. * @return bool True on success or false on failure. * @throws \moodle_exception */ public static function move_courses_into_category($categoryorid, $courseids = array()) { global $DB; if (!is_array($courseids)) { // Just a single course ID. $courseids = array($courseids); } // Bulk move courses from one category to another. if (count($courseids) === 0) { return false; } if ($categoryorid instanceof \core_course_category) { $moveto = $categoryorid; } else { $moveto = \core_course_category::get($categoryorid); } if (!$moveto->can_move_courses_out_of() || !$moveto->can_move_courses_into()) { throw new \moodle_exception('cannotmovecourses'); } list($where, $params) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED); $sql = "SELECT c.id, c.category FROM {course} c WHERE c.id {$where}"; $courses = $DB->get_records_sql($sql, $params); $checks = array(); foreach ($courseids as $id) { if (!isset($courses[$id])) { throw new \moodle_exception('invalidcourseid'); } $catid = $courses[$id]->category; if (!isset($checks[$catid])) { $coursecat = \core_course_category::get($catid); $checks[$catid] = $coursecat->can_move_courses_out_of() && $coursecat->can_move_courses_into(); } if (!$checks[$catid]) { throw new \moodle_exception('cannotmovecourses'); } } return \move_courses($courseids, $moveto->id); } /** * Returns an array of courseids and visiblity for all courses within the given category. * @param int $categoryid * @return array */ public static function get_category_courses_visibility($categoryid) { global $DB; $sql = "SELECT c.id, c.visible FROM {course} c WHERE c.category = :category"; $params = array('category' => (int)$categoryid); return $DB->get_records_sql($sql, $params); } /** * Returns an array of all categoryids that have the given category as a parent and their visible value. * @param int $categoryid * @return array */ public static function get_category_children_visibility($categoryid) { global $DB; $category = \core_course_category::get($categoryid); $select = $DB->sql_like('path', ':path'); $path = $category->path . '/%'; $sql = "SELECT c.id, c.visible FROM {course_categories} c WHERE ".$select; $params = array('path' => $path); return $DB->get_records_sql($sql, $params); } /** * Records when a category is expanded or collapsed so that when the user * * @param \core_course_category $coursecat The category we're working with. * @param bool $expanded True if the category is expanded now. */ public static function record_expanded_category(\core_course_category $coursecat, $expanded = true) { // If this ever changes we are going to reset it and reload the categories as required. self::$expandedcategories = null; $categoryid = $coursecat->id; $path = $coursecat->get_parents(); /* @var \cache_session $cache */ $cache = \cache::make('core', 'userselections'); $categories = $cache->get('categorymanagementexpanded'); if (!is_array($categories)) { if (!$expanded) { // No categories recorded, nothing to remove. return; } $categories = array(); } if ($expanded) { $ref =& $categories; foreach ($coursecat->get_parents() as $path) { if (!isset($ref[$path]) || !is_array($ref[$path])) { $ref[$path] = array(); } $ref =& $ref[$path]; } if (!isset($ref[$categoryid])) { $ref[$categoryid] = true; } } else { $found = true; $ref =& $categories; foreach ($coursecat->get_parents() as $path) { if (!isset($ref[$path])) { $found = false; break; } $ref =& $ref[$path]; } if ($found) { $ref[$categoryid] = null; unset($ref[$categoryid]); } } $cache->set('categorymanagementexpanded', $categories); } /** * Returns the categories that should be expanded when displaying the interface. * * @param int|null $withpath If specified a path to require as the parent. * @return \core_course_category[] An array of Category ID's to expand. */ public static function get_expanded_categories($withpath = null) { if (self::$expandedcategories === null) { /* @var \cache_session $cache */ $cache = \cache::make('core', 'userselections'); self::$expandedcategories = $cache->get('categorymanagementexpanded'); if (self::$expandedcategories === false) { self::$expandedcategories = array(); } } if (empty($withpath)) { return array_keys(self::$expandedcategories); } $parents = explode('/', trim($withpath, '/')); $ref =& self::$expandedcategories; foreach ($parents as $parent) { if (!isset($ref[$parent])) { return array(); } $ref =& $ref[$parent]; } if (is_array($ref)) { return array_keys($ref); } else { return array($parent); } } /** * Get an array of the capabilities required to copy a course. * * @return array */ public static function get_course_copy_capabilities(): array { return array('moodle/backup:backupcourse', 'moodle/restore:restorecourse', 'moodle/course:view', 'moodle/course:create'); } /** * Returns true if the current user can copy this course. * * @param int $courseid * @return bool */ public static function can_copy_course(int $courseid): bool { $coursecontext = \context_course::instance($courseid); return has_all_capabilities(self::get_course_copy_capabilities(), $coursecontext); } } home3/cpr76684/public_html/Aem/contentbank/classes/helper.php 0000644 00000007204 15152206447 0017732 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Contains helper class for the content bank. * * @package core_contentbank * @copyright 2020 Amaia Anabitarte <amaia@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_contentbank; /** * Helper class for the content bank. * * @package core_contentbank * @copyright 2020 Amaia Anabitarte <amaia@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class helper { /** * Getting content bank page ready for the breadcrumbs. * * @param \context $context Context of the current page. * @param string $title Title of the current page. * @param bool $internal True if is an internal page, false otherwise. */ public static function get_page_ready(\context $context, string $title, bool $internal = false): void { global $PAGE, $DB; $PAGE->set_context($context); $PAGE->set_heading(self::get_page_heading($context)); $PAGE->set_secondary_active_tab('contentbank'); $cburl = new \moodle_url('/contentbank/index.php', ['contextid' => $context->id]); switch ($context->contextlevel) { case CONTEXT_COURSE: $courseid = $context->instanceid; $course = $DB->get_record('course', ['id' => $courseid], '*', MUST_EXIST); $PAGE->set_course($course); \navigation_node::override_active_url(new \moodle_url('/course/view.php', ['id' => $courseid])); $PAGE->navbar->add($title, $cburl); $PAGE->set_pagelayout('incourse'); break; case CONTEXT_COURSECAT: $coursecat = $context->instanceid; \navigation_node::override_active_url(new \moodle_url('/course/index.php', ['categoryid' => $coursecat])); $PAGE->navbar->add($title, $cburl); $PAGE->set_pagelayout('coursecategory'); break; default: if ($node = $PAGE->navigation->find('contentbank', \global_navigation::TYPE_CUSTOM)) { $node->make_active(); } $PAGE->set_pagelayout('standard'); } } /** * Get the page heading based on the current context * * @param \context $context The current context of the page * @return string */ public static function get_page_heading(\context $context): string { global $SITE; $title = get_string('contentbank'); if ($context->id == \context_system::instance()->id) { $title = $SITE->fullname; } else if ($context->contextlevel == CONTEXT_COURSE) { $course = get_course($context->instanceid); $title = $course->fullname; } else if ($context->contextlevel == CONTEXT_COURSECAT) { $category = \core_course_category::get($context->instanceid); $title = $category->get_formatted_name(); } return $title; } } home3/cpr76684/public_html/Aem/mod/lti/classes/helper.php 0000644 00000004475 15152540333 0016775 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. namespace mod_lti; defined('MOODLE_INTERNAL') || die(); /** * Helper class for LTI activity. * * @package mod_lti * @author Andrew Madden <andrewmadden@catalyst-au.net> * @copyright 2020 Catalyst IT * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class helper { /** * Get SQL to query DB for LTI tool proxy records. * * @param bool $orphanedonly If true, return SQL to get orphaned proxies only. * @param bool $count If true, return SQL to get the count of the records instead of the records themselves. * @return string SQL. */ public static function get_tool_proxy_sql(bool $orphanedonly = false, bool $count = false): string { if ($count) { $select = "SELECT count(*) as type_count"; $sort = ""; } else { // We only want the fields from lti_tool_proxies table. Must define every column to be compatible with mysqli. $select = "SELECT ltp.id, ltp.name, ltp.regurl, ltp.state, ltp.guid, ltp.secret, ltp.vendorcode, ltp.capabilityoffered, ltp.serviceoffered, ltp.toolproxy, ltp.createdby, ltp.timecreated, ltp.timemodified"; $sort = " ORDER BY ltp.name ASC, ltp.state DESC, ltp.timemodified DESC"; } $from = " FROM {lti_tool_proxies} ltp"; if ($orphanedonly) { $join = " LEFT JOIN {lti_types} lt ON ltp.id = lt.toolproxyid"; $where = " WHERE lt.toolproxyid IS null"; } else { $join = ""; $where = ""; } return $select . $from . $join . $where . $sort; } }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | ���֧ߧ֧�ѧ�ڧ� ����ѧߧڧ��: 0 |
proxy
|
phpinfo
|
���ѧ����ۧܧ�