function filter($text, array $options = array()) { $coursectx = $this->context->get_course_context(false); if (!$coursectx) { return $text; } $courseid = $coursectx->instanceid; // Initialise/invalidate our trivial cache if dealing with a different course if (!isset(self::$cachedcourseid) || self::$cachedcourseid !== (int) $courseid) { self::$activitylist = null; } self::$cachedcourseid = (int) $courseid; /// It may be cached if (is_null(self::$activitylist)) { self::$activitylist = array(); $modinfo = get_fast_modinfo($courseid); if (!empty($modinfo->cms)) { self::$activitylist = array(); // We will store all the created filters here. // Create array of visible activities sorted by the name length (we are only interested in properties name and url). $sortedactivities = array(); foreach ($modinfo->cms as $cm) { // Exclude labels, hidden activities and activities for group members only. if ($cm->visible and empty($cm->groupmembersonly) and $cm->has_view()) { $sortedactivities[] = (object) array('name' => $cm->name, 'url' => $cm->url, 'id' => $cm->id, 'namelen' => strlen($cm->name)); } } core_collator::asort_objects_by_property($sortedactivities, 'namelen', SORT_NUMERIC); foreach ($sortedactivities as $cm) { $title = s(trim(strip_tags($cm->name))); $currentname = trim($cm->name); $entitisedname = s($currentname); // Avoid empty or unlinkable activity names. if (!empty($title)) { $href_tag_begin = html_writer::start_tag('a', array('class' => 'autolink', 'title' => $title, 'href' => $cm->url)); self::$activitylist[$cm->id] = new filterobject($currentname, $href_tag_begin, '</a>', false, true); if ($currentname != $entitisedname) { // If name has some entity (& " < >) add that filter too. MDL-17545. self::$activitylist[$cm->id . '-e'] = new filterobject($entitisedname, $href_tag_begin, '</a>', false, true); } } } } } $filterslist = array(); if (self::$activitylist) { $cmid = $this->context->instanceid; if ($this->context->contextlevel == CONTEXT_MODULE && isset(self::$activitylist[$cmid])) { // remove filterobjects for the current module $filterslist = array_values(array_diff_key(self::$activitylist, array($cmid => 1, $cmid . '-e' => 1))); } else { $filterslist = array_values(self::$activitylist); } } if ($filterslist) { return $text = filter_phrases($text, $filterslist); } else { return $text; } }
/** * Set the global activated state for a text filter. * * @param string $filtername The filter name, for example 'tex'. * @param int $state One of the values TEXTFILTER_ON, TEXTFILTER_OFF or TEXTFILTER_DISABLED. * @param int $move -1 means up, 0 means the same, 1 means down */ function filter_set_global_state($filtername, $state, $move = 0) { global $DB; // Check requested state is valid. if (!in_array($state, array(TEXTFILTER_ON, TEXTFILTER_OFF, TEXTFILTER_DISABLED))) { throw new coding_exception("Illegal option '{$state}' passed to filter_set_global_state. " . "Must be one of TEXTFILTER_ON, TEXTFILTER_OFF or TEXTFILTER_DISABLED."); } if ($move > 0) { $move = 1; } else { if ($move < 0) { $move = -1; } } if (strpos($filtername, 'filter/') === 0) { //debugging("Old filtername '$filtername' parameter used in filter_set_global_state()", DEBUG_DEVELOPER); $filtername = substr($filtername, 7); } else { if (strpos($filtername, '/') !== false) { throw new coding_exception("Invalid filter name '{$filtername}' used in filter_set_global_state()"); } } $transaction = $DB->start_delegated_transaction(); $syscontext = context_system::instance(); $filters = $DB->get_records('filter_active', array('contextid' => $syscontext->id), 'sortorder ASC'); $on = array(); $off = array(); foreach ($filters as $f) { if ($f->active == TEXTFILTER_DISABLED) { $off[$f->filter] = $f; } else { $on[$f->filter] = $f; } } // Update the state or add new record. if (isset($on[$filtername])) { $filter = $on[$filtername]; if ($filter->active != $state) { add_to_config_log('filter_active', $filter->active, $state, $filtername); $filter->active = $state; $DB->update_record('filter_active', $filter); if ($filter->active == TEXTFILTER_DISABLED) { unset($on[$filtername]); $off = array($filter->filter => $filter) + $off; } } } else { if (isset($off[$filtername])) { $filter = $off[$filtername]; if ($filter->active != $state) { add_to_config_log('filter_active', $filter->active, $state, $filtername); $filter->active = $state; $DB->update_record('filter_active', $filter); if ($filter->active != TEXTFILTER_DISABLED) { unset($off[$filtername]); $on[$filter->filter] = $filter; } } } else { add_to_config_log('filter_active', '', $state, $filtername); $filter = new stdClass(); $filter->filter = $filtername; $filter->contextid = $syscontext->id; $filter->active = $state; $filter->sortorder = 99999; $filter->id = $DB->insert_record('filter_active', $filter); $filters[$filter->id] = $filter; if ($state == TEXTFILTER_DISABLED) { $off[$filter->filter] = $filter; } else { $on[$filter->filter] = $filter; } } } // Move only active. if ($move != 0 and isset($on[$filter->filter])) { $i = 1; foreach ($on as $f) { $f->newsortorder = $i; $i++; } $filter->newsortorder = $filter->newsortorder + $move; foreach ($on as $f) { if ($f->id == $filter->id) { continue; } if ($f->newsortorder == $filter->newsortorder) { if ($move == 1) { $f->newsortorder = $f->newsortorder - 1; } else { $f->newsortorder = $f->newsortorder + 1; } } } core_collator::asort_objects_by_property($on, 'newsortorder', core_collator::SORT_NUMERIC); } // Inactive are sorted by filter name. core_collator::asort_objects_by_property($off, 'filter', core_collator::SORT_NATURAL); // Update records if necessary. $i = 1; foreach ($on as $f) { if ($f->sortorder != $i) { $DB->set_field('filter_active', 'sortorder', $i, array('id' => $f->id)); } $i++; } foreach ($off as $f) { if ($f->sortorder != $i) { $DB->set_field('filter_active', 'sortorder', $i, array('id' => $f->id)); } $i++; } $transaction->allow_commit(); }
/** * Returns the children associated with this category. * * @return part_of_admin_tree[] */ public function get_children() { // If we should sort and it hasn't already been sorted. if ($this->sort && !$this->sorted) { if ($this->sortsplit) { $categories = array(); $pages = array(); foreach ($this->children as $child) { if ($child instanceof admin_category) { $categories[] = $child; } else { $pages[] = $child; } } core_collator::asort_objects_by_property($categories, 'visiblename'); core_collator::asort_objects_by_property($pages, 'visiblename'); if (!$this->sortasc) { $categories = array_reverse($categories); $pages = array_reverse($pages); } $this->children = array_merge($pages, $categories); } else { core_collator::asort_objects_by_property($this->children, 'visiblename'); if (!$this->sortasc) { $this->children = array_reverse($this->children); } } $this->sorted = true; } return $this->children; }
/** * Resort the courses within this category by the given field. * * @param string $field One of fullname, shortname, idnumber or descending values of each (appended desc) * @param bool $cleanup * @return bool True for success. * @throws coding_exception */ public function resort_courses($field, $cleanup = true) { global $DB; $desc = false; if (substr($field, -4) === "desc") { $desc = true; $field = substr($field, 0, -4); // Remove "desc" from field name. } if ($field !== 'fullname' && $field !== 'shortname' && $field !== 'idnumber' && $field !== 'timecreated') { // This is ultra important as we use $field in an SQL statement below this. throw new coding_exception('Invalid field requested'); } $ctxfields = context_helper::get_preload_record_columns_sql('ctx'); $sql = "SELECT c.id, c.sortorder, c.{$field}, {$ctxfields}\n FROM {course} c\n LEFT JOIN {context} ctx ON ctx.instanceid = c.id\n WHERE ctx.contextlevel = :ctxlevel AND\n c.category = :categoryid"; $params = array('ctxlevel' => CONTEXT_COURSE, 'categoryid' => $this->id); $courses = $DB->get_records_sql($sql, $params); if (count($courses) > 0) { foreach ($courses as $courseid => $course) { context_helper::preload_from_record($course); if ($field === 'idnumber') { $course->sortby = $course->idnumber; } else { // It'll require formatting. $options = array('context' => context_course::instance($course->id)); // We format the string first so that it appears as the user would see it. // This ensures the sorting makes sense to them. However it won't necessarily make // sense to everyone if things like multilang filters are enabled. // We then strip any tags as we don't want things such as image tags skewing the // sort results. $course->sortby = strip_tags(format_string($course->{$field}, true, $options)); } // We set it back here rather than using references as there is a bug with using // references in a foreach before passing as an arg by reference. $courses[$courseid] = $course; } // Sort the courses. core_collator::asort_objects_by_property($courses, 'sortby', core_collator::SORT_NATURAL); if (!empty($desc)) { $courses = array_reverse($courses); } $i = 1; foreach ($courses as $course) { $DB->set_field('course', 'sortorder', $this->sortorder + $i, array('id' => $course->id)); $i++; } if ($cleanup) { // This should not be needed but we do it just to be safe. fix_course_sortorder(); cache_helper::purge_by_event('changesincourse'); } } return true; }
/** * Retrieve the messages between two users * * @param object $user1 the current user * @param object $user2 the other user * @param int $limitnum the maximum number of messages to retrieve * @param bool $viewingnewmessages are we currently viewing new messages? */ function message_get_history($user1, $user2, $limitnum=0, $viewingnewmessages=false) { global $DB, $CFG; $messages = array(); //we want messages sorted oldest to newest but if getting a subset of messages we need to sort //desc to get the last $limitnum messages then flip the order in php $sort = 'asc'; if ($limitnum>0) { $sort = 'desc'; } $notificationswhere = null; //we have just moved new messages to read. If theyre here to see new messages dont hide notifications if (!$viewingnewmessages && $CFG->messaginghidereadnotifications) { $notificationswhere = 'AND notification=0'; } //prevent notifications of your own actions appearing in your own message history $ownnotificationwhere = ' AND NOT (useridfrom=? AND notification=1)'; $sql = "((useridto = ? AND useridfrom = ? AND timeusertodeleted = 0) OR (useridto = ? AND useridfrom = ? AND timeuserfromdeleted = 0))"; if ($messages_read = $DB->get_records_select('message_read', $sql . $notificationswhere . $ownnotificationwhere, array($user1->id, $user2->id, $user2->id, $user1->id, $user1->id), "timecreated $sort", '*', 0, $limitnum)) { foreach ($messages_read as $message) { $messages[] = $message; } } if ($messages_new = $DB->get_records_select('message', $sql . $ownnotificationwhere, array($user1->id, $user2->id, $user2->id, $user1->id, $user1->id), "timecreated $sort", '*', 0, $limitnum)) { foreach ($messages_new as $message) { $messages[] = $message; } } $result = core_collator::asort_objects_by_property($messages, 'timecreated', core_collator::SORT_NUMERIC); //if we only want the last $limitnum messages $messagecount = count($messages); if ($limitnum > 0 && $messagecount > $limitnum) { $messages = array_slice($messages, $messagecount - $limitnum, $limitnum, true); } return $messages; }
/** * Tests the static asort_objects_by_method method. */ public function test_asort_objects_by_property() { $objects = array('b' => new string_test_class('ab'), 1 => new string_test_class('aa'), 0 => new string_test_class('cc')); $result = core_collator::asort_objects_by_property($objects, 'publicname'); $this->assertSame(array(1, 'b', 0), array_keys($objects)); $this->assertSame(array('aa', 'ab', 'cc'), $this->get_ordered_names($objects, 'publicname')); $this->assertTrue($result); $objects = array('b' => new string_test_class('a20'), 1 => new string_test_class('a1'), 0 => new string_test_class('a100')); $result = core_collator::asort_objects_by_property($objects, 'publicname', core_collator::SORT_NATURAL); $this->assertSame(array(1, 'b', 0), array_keys($objects)); $this->assertSame(array('a1', 'a20', 'a100'), $this->get_ordered_names($objects, 'publicname')); $this->assertTrue($result); }
} if ($swapcategory and $movecategory) { $DB->set_field('course_categories', 'sortorder', $swapcategory->sortorder, array('id' => $movecategory->id)); $DB->set_field('course_categories', 'sortorder', $movecategory->sortorder, array('id' => $swapcategory->id)); cache_helper::purge_by_event('changesincoursecat'); add_to_log(SITEID, "category", "move", "editcategory.php?id=$movecategory->id", $movecategory->id); } // Finally reorder courses. fix_course_sortorder(); } if ($coursecat->id && $canmanage && $resort && confirm_sesskey()) { // Resort the category. if ($courses = get_courses($coursecat->id, '', 'c.id,c.fullname,c.sortorder')) { core_collator::asort_objects_by_property($courses, 'fullname', core_collator::SORT_NATURAL); $i = 1; foreach ($courses as $course) { $DB->set_field('course', 'sortorder', $coursecat->sortorder + $i, array('id' => $course->id)); $i++; } // This should not be needed but we do it just to be safe. fix_course_sortorder(); cache_helper::purge_by_event('changesincourse'); } } if (!empty($moveto) && ($data = data_submitted()) && confirm_sesskey()) { // Move a specified course to a new category. // User must have category update in both cats to perform this. require_capability('moodle/category:manage', $context);
/** * Given a course and a time, this module should find recent activity * that has occurred in workshop activities and print it out. * Return true if there was output, or false is there was none. * * @param stdClass $course * @param bool $viewfullnames * @param int $timestart * @return boolean */ function workshop_print_recent_activity($course, $viewfullnames, $timestart) { global $CFG, $USER, $DB, $OUTPUT; $authoramefields = get_all_user_name_fields(true, 'author', null, 'author'); $reviewerfields = get_all_user_name_fields(true, 'reviewer', null, 'reviewer'); $sql = "SELECT s.id AS submissionid, s.title AS submissiontitle, s.timemodified AS submissionmodified, author.id AS authorid, $authoramefields, a.id AS assessmentid, a.timemodified AS assessmentmodified, reviewer.id AS reviewerid, $reviewerfields, cm.id AS cmid FROM {workshop} w INNER JOIN {course_modules} cm ON cm.instance = w.id INNER JOIN {modules} md ON md.id = cm.module INNER JOIN {workshop_submissions} s ON s.workshopid = w.id INNER JOIN {user} author ON s.authorid = author.id LEFT JOIN {workshop_assessments} a ON a.submissionid = s.id LEFT JOIN {user} reviewer ON a.reviewerid = reviewer.id WHERE cm.course = ? AND md.name = 'workshop' AND s.example = 0 AND (s.timemodified > ? OR a.timemodified > ?) ORDER BY s.timemodified"; $rs = $DB->get_recordset_sql($sql, array($course->id, $timestart, $timestart)); $modinfo = get_fast_modinfo($course); // reference needed because we might load the groups $submissions = array(); // recent submissions indexed by submission id $assessments = array(); // recent assessments indexed by assessment id $users = array(); foreach ($rs as $activity) { if (!array_key_exists($activity->cmid, $modinfo->cms)) { // this should not happen but just in case continue; } $cm = $modinfo->cms[$activity->cmid]; if (!$cm->uservisible) { continue; } // remember all user names we can use later if (empty($users[$activity->authorid])) { $u = new stdclass(); $users[$activity->authorid] = username_load_fields_from_object($u, $activity, 'author'); } if ($activity->reviewerid and empty($users[$activity->reviewerid])) { $u = new stdclass(); $users[$activity->reviewerid] = username_load_fields_from_object($u, $activity, 'reviewer'); } $context = context_module::instance($cm->id); $groupmode = groups_get_activity_groupmode($cm, $course); if ($activity->submissionmodified > $timestart and empty($submissions[$activity->submissionid])) { $s = new stdclass(); $s->title = $activity->submissiontitle; $s->authorid = $activity->authorid; $s->timemodified = $activity->submissionmodified; $s->cmid = $activity->cmid; if ($activity->authorid == $USER->id || has_capability('mod/workshop:viewauthornames', $context)) { $s->authornamevisible = true; } else { $s->authornamevisible = false; } // the following do-while wrapper allows to break from deeply nested if-statements do { if ($s->authorid === $USER->id) { // own submissions always visible $submissions[$activity->submissionid] = $s; break; } if (has_capability('mod/workshop:viewallsubmissions', $context)) { if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) { if (isguestuser()) { // shortcut - guest user does not belong into any group break; } // this might be slow - show only submissions by users who share group with me in this cm if (!$modinfo->get_groups($cm->groupingid)) { break; } $authorsgroups = groups_get_all_groups($course->id, $s->authorid, $cm->groupingid); if (is_array($authorsgroups)) { $authorsgroups = array_keys($authorsgroups); $intersect = array_intersect($authorsgroups, $modinfo->get_groups($cm->groupingid)); if (empty($intersect)) { break; } else { // can see all submissions and shares a group with the author $submissions[$activity->submissionid] = $s; break; } } } else { // can see all submissions from all groups $submissions[$activity->submissionid] = $s; } } } while (0); } if ($activity->assessmentmodified > $timestart and empty($assessments[$activity->assessmentid])) { $a = new stdclass(); $a->submissionid = $activity->submissionid; $a->submissiontitle = $activity->submissiontitle; $a->reviewerid = $activity->reviewerid; $a->timemodified = $activity->assessmentmodified; $a->cmid = $activity->cmid; if ($activity->reviewerid == $USER->id || has_capability('mod/workshop:viewreviewernames', $context)) { $a->reviewernamevisible = true; } else { $a->reviewernamevisible = false; } // the following do-while wrapper allows to break from deeply nested if-statements do { if ($a->reviewerid === $USER->id) { // own assessments always visible $assessments[$activity->assessmentid] = $a; break; } if (has_capability('mod/workshop:viewallassessments', $context)) { if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) { if (isguestuser()) { // shortcut - guest user does not belong into any group break; } // this might be slow - show only submissions by users who share group with me in this cm if (!$modinfo->get_groups($cm->groupingid)) { break; } $reviewersgroups = groups_get_all_groups($course->id, $a->reviewerid, $cm->groupingid); if (is_array($reviewersgroups)) { $reviewersgroups = array_keys($reviewersgroups); $intersect = array_intersect($reviewersgroups, $modinfo->get_groups($cm->groupingid)); if (empty($intersect)) { break; } else { // can see all assessments and shares a group with the reviewer $assessments[$activity->assessmentid] = $a; break; } } } else { // can see all assessments from all groups $assessments[$activity->assessmentid] = $a; } } } while (0); } } $rs->close(); $shown = false; if (!empty($submissions)) { $shown = true; echo $OUTPUT->heading(get_string('recentsubmissions', 'workshop'), 3); foreach ($submissions as $id => $submission) { $link = new moodle_url('/mod/workshop/submission.php', array('id'=>$id, 'cmid'=>$submission->cmid)); if ($submission->authornamevisible) { $author = $users[$submission->authorid]; } else { $author = null; } print_recent_activity_note($submission->timemodified, $author, $submission->title, $link->out(), false, $viewfullnames); } } if (!empty($assessments)) { $shown = true; echo $OUTPUT->heading(get_string('recentassessments', 'workshop'), 3); core_collator::asort_objects_by_property($assessments, 'timemodified'); foreach ($assessments as $id => $assessment) { $link = new moodle_url('/mod/workshop/assessment.php', array('asid' => $id)); if ($assessment->reviewernamevisible) { $reviewer = $users[$assessment->reviewerid]; } else { $reviewer = null; } print_recent_activity_note($assessment->timemodified, $reviewer, $assessment->submissiontitle, $link->out(), false, $viewfullnames); } } if ($shown) { return true; } return false; }
/** * Get the users recent conversations meaning all the people they've recently * sent or received a message from plus the most recent message sent to or received from each other user * * @param object|int $userorid the current user or user id * @param int $limitfrom can be used for paging * @param int $limitto can be used for paging * @return array */ function message_get_recent_conversations($userorid, $limitfrom = 0, $limitto = 100) { global $DB; if (is_object($userorid)) { $user = $userorid; } else { $userid = $userorid; $user = new stdClass(); $user->id = $userid; } $userfields = user_picture::fields('otheruser', array('lastaccess')); // This query retrieves the most recent message received from or sent to // seach other user. // // If two messages have the same timecreated, we take the one with the // larger id. // // There is a separate query for read and unread messages as they are stored // in different tables. They were originally retrieved in one query but it // was so large that it was difficult to be confident in its correctness. $uniquefield = $DB->sql_concat('message.useridfrom', "'-'", 'message.useridto'); $sql = "SELECT $uniquefield, $userfields, message.id as mid, message.notification, message.useridfrom, message.useridto, message.smallmessage, message.fullmessage, message.fullmessagehtml, message.fullmessageformat, message.timecreated, contact.id as contactlistid, contact.blocked FROM {message_read} message JOIN ( SELECT MAX(id) AS messageid, matchedmessage.useridto, matchedmessage.useridfrom FROM {message_read} matchedmessage INNER JOIN ( SELECT MAX(recentmessages.timecreated) timecreated, recentmessages.useridfrom, recentmessages.useridto FROM {message_read} recentmessages WHERE ( (recentmessages.useridfrom = :userid1 AND recentmessages.timeuserfromdeleted = 0) OR (recentmessages.useridto = :userid2 AND recentmessages.timeusertodeleted = 0) ) GROUP BY recentmessages.useridfrom, recentmessages.useridto ) recent ON matchedmessage.useridto = recent.useridto AND matchedmessage.useridfrom = recent.useridfrom AND matchedmessage.timecreated = recent.timecreated WHERE ( (matchedmessage.useridfrom = :userid6 AND matchedmessage.timeuserfromdeleted = 0) OR (matchedmessage.useridto = :userid7 AND matchedmessage.timeusertodeleted = 0) ) GROUP BY matchedmessage.useridto, matchedmessage.useridfrom ) messagesubset ON messagesubset.messageid = message.id JOIN {user} otheruser ON (message.useridfrom = :userid4 AND message.useridto = otheruser.id) OR (message.useridto = :userid5 AND message.useridfrom = otheruser.id) LEFT JOIN {message_contacts} contact ON contact.userid = :userid3 AND contact.contactid = otheruser.id WHERE otheruser.deleted = 0 AND message.notification = 0 ORDER BY message.timecreated DESC"; $params = array( 'userid1' => $user->id, 'userid2' => $user->id, 'userid3' => $user->id, 'userid4' => $user->id, 'userid5' => $user->id, 'userid6' => $user->id, 'userid7' => $user->id ); $read = $DB->get_records_sql($sql, $params, $limitfrom, $limitto); // We want to get the messages that have not been read. These are stored in the 'message' table. It is the // exact same query as the one above, except for the table we are querying. So, simply replace references to // the 'message_read' table with the 'message' table. $sql = str_replace('{message_read}', '{message}', $sql); $unread = $DB->get_records_sql($sql, $params, $limitfrom, $limitto); $unreadcountssql = 'SELECT useridfrom, count(*) as count FROM {message} WHERE useridto = :userid AND timeusertodeleted = 0 AND notification = 0 GROUP BY useridfrom'; $unreadcounts = $DB->get_records_sql($unreadcountssql, array('userid' => $user->id)); // Union the 2 result sets together looking for the message with the most // recent timecreated for each other user. // $conversation->id (the array key) is the other user's ID. $conversations = array(); $conversation_arrays = array($unread, $read); foreach ($conversation_arrays as $conversation_array) { foreach ($conversation_array as $conversation) { // Only consider it unread if $user has unread messages. if (isset($unreadcounts[$conversation->useridfrom])) { $conversation->isread = 0; $conversation->unreadcount = $unreadcounts[$conversation->useridfrom]->count; } else { $conversation->isread = 1; } if (!isset($conversations[$conversation->id])) { $conversations[$conversation->id] = $conversation; } else { $current = $conversations[$conversation->id]; // We need to maintain the isread and unreadcount values from existing // parts of the conversation if we're replacing it. $conversation->isread = ($conversation->isread && $current->isread); if (isset($current->unreadcount) && !isset($conversation->unreadcount)) { $conversation->unreadcount = $current->unreadcount; } if ($current->timecreated < $conversation->timecreated) { $conversations[$conversation->id] = $conversation; } else if ($current->timecreated == $conversation->timecreated) { if ($current->mid < $conversation->mid) { $conversations[$conversation->id] = $conversation; } } } } } // Sort the conversations by $conversation->timecreated, newest to oldest // There may be multiple conversations with the same timecreated // The conversations array contains both read and unread messages (different tables) so sorting by ID won't work $result = core_collator::asort_objects_by_property($conversations, 'timecreated', core_collator::SORT_NUMERIC); $conversations = array_reverse($conversations); return $conversations; }
$settingspath = $path . '/settings.php'; if (file_exists($settingspath)) { $settings = new admin_settingpage('cachestore_' . $plugin . '_settings', new lang_string('pluginname', 'cachestore_' . $plugin), 'moodle/site:config'); include $settingspath; $ADMIN->add('cachestores', $settings); } } } // Add Calendar type settings. if ($hassiteconfig) { $ADMIN->add('modules', new admin_category('calendartype', new lang_string('calendartypes', 'calendar'))); $plugins = core_plugin_manager::instance()->get_plugins_of_type('calendartype'); core_collator::asort_objects_by_property($plugins, 'displayname'); foreach ($plugins as $plugin) { /** @var \core\plugininfo\calendartype $plugin */ $plugin->load_settings($ADMIN, 'calendartype', $hassiteconfig); } } /// Add all local plugins - must be always last! if ($hassiteconfig) { $ADMIN->add('modules', new admin_category('localplugins', new lang_string('localplugins'))); $ADMIN->add('localplugins', new admin_externalpage('managelocalplugins', new lang_string('localpluginsmanage'), $CFG->wwwroot . '/' . $CFG->admin . '/localplugins.php')); } // Extend settings for each local plugin. Note that their settings may be in any part of the // settings tree and may be visible not only for administrators. $plugins = core_plugin_manager::instance()->get_plugins_of_type('local'); core_collator::asort_objects_by_property($plugins, 'displayname'); foreach ($plugins as $plugin) { /** @var \core\plugininfo\local $plugin */ $plugin->load_settings($ADMIN, null, $hassiteconfig); }
/** * Retrieve all metadata for the requested modules * * @param object $course The Course * @param array $modnames An array containing the list of modules and their * names * @param int $sectionreturn The section to return to * @return array A list of stdClass objects containing metadata about each * module */ function get_module_metadata($course, $modnames, $sectionreturn = null) { global $OUTPUT; // get_module_metadata will be called once per section on the page and courses may show // different modules to one another static $modlist = array(); if (!isset($modlist[$course->id])) { $modlist[$course->id] = array(); } $return = array(); $urlbase = new moodle_url('/course/mod.php', array('id' => $course->id, 'sesskey' => sesskey())); if ($sectionreturn !== null) { $urlbase->param('sr', $sectionreturn); } foreach ($modnames as $modname => $modnamestr) { if (!course_allowed_module($course, $modname)) { continue; } if (isset($modlist[$course->id][$modname])) { // This module is already cached $return += $modlist[$course->id][$modname]; continue; } $modlist[$course->id][$modname] = array(); // Create an object for a default representation of this module type in the activity chooser. It will be used // if module does not implement callback get_shortcuts() and it will also be passed to the callback if it exists. $defaultmodule = new stdClass(); $defaultmodule->title = $modnamestr; $defaultmodule->name = $modname; $defaultmodule->link = new moodle_url($urlbase, array('add' => $modname)); $defaultmodule->icon = $OUTPUT->pix_icon('icon', '', $defaultmodule->name, array('class' => 'icon')); $sm = get_string_manager(); if ($sm->string_exists('modulename_help', $modname)) { $defaultmodule->help = get_string('modulename_help', $modname); if ($sm->string_exists('modulename_link', $modname)) { // Link to further info in Moodle docs. $link = get_string('modulename_link', $modname); $linktext = get_string('morehelp'); $defaultmodule->help .= html_writer::tag('div', $OUTPUT->doc_link($link, $linktext, true), array('class' => 'helpdoclink')); } } $defaultmodule->archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); // Legacy support for callback get_types() - do not use any more, use get_shortcuts() instead! $typescallbackexists = component_callback_exists($modname, 'get_types'); // Each module can implement callback modulename_get_shortcuts() in its lib.php and return the list // of elements to be added to activity chooser. $items = component_callback($modname, 'get_shortcuts', array($defaultmodule), null); if ($items !== null) { foreach ($items as $item) { // Add all items to the return array. All items must have different links, use them as a key in the return array. if (!isset($item->archetype)) { $item->archetype = $defaultmodule->archetype; } if (!isset($item->icon)) { $item->icon = $defaultmodule->icon; } // If plugin returned the only one item with the same link as default item - cache it as $modname, // otherwise append the link url to the module name. $item->name = count($items) == 1 && $item->link->out() === $defaultmodule->link->out() ? $modname : $modname . ':' . $item->link; // If the module provides the helptext property, append it to the help text to match the look and feel // of the default course modules. if (isset($item->help) && isset($item->helplink)) { $linktext = get_string('morehelp'); $item->help .= html_writer::tag('div', $OUTPUT->doc_link($item->helplink, $linktext, true), array('class' => 'helpdoclink')); } $modlist[$course->id][$modname][$item->name] = $item; } $return += $modlist[$course->id][$modname]; if ($typescallbackexists) { debugging('Both callbacks get_shortcuts() and get_types() are found in module ' . $modname . '. Callback get_types() will be completely ignored', DEBUG_DEVELOPER); } // If get_shortcuts() callback is defined, the default module action is not added. // It is a responsibility of the callback to add it to the return value unless it is not needed. continue; } if ($typescallbackexists) { debugging('Callback get_types() is found in module ' . $modname . ', this functionality is deprecated, ' . 'please use callback get_shortcuts() instead', DEBUG_DEVELOPER); } $types = component_callback($modname, 'get_types', array(), MOD_SUBTYPE_NO_CHILDREN); if ($types !== MOD_SUBTYPE_NO_CHILDREN) { // Legacy support for deprecated callback get_types(). To be removed in Moodle 3.5. TODO MDL-53697. if (is_array($types) && count($types) > 0) { $grouptitle = $modnamestr; $icon = $OUTPUT->pix_icon('icon', '', $modname, array('class' => 'icon')); foreach ($types as $type) { if ($type->typestr === '--') { continue; } if (strpos($type->typestr, '--') === 0) { $grouptitle = str_replace('--', '', $type->typestr); continue; } // Set the Sub Type metadata. $subtype = new stdClass(); $subtype->title = get_string('activitytypetitle', '', (object) ['activity' => $grouptitle, 'type' => $type->typestr]); $subtype->type = str_replace('&', '&', $type->type); $typename = preg_replace('/.*type=/', '', $subtype->type); $subtype->archetype = $type->modclass; if (!empty($type->help)) { $subtype->help = $type->help; } else { if (get_string_manager()->string_exists('help' . $subtype->name, $modname)) { $subtype->help = get_string('help' . $subtype->name, $modname); } } $subtype->link = new moodle_url($urlbase, array('add' => $modname, 'type' => $typename)); $subtype->name = $modname . ':' . $subtype->link; $subtype->icon = $icon; $modlist[$course->id][$modname][$subtype->name] = $subtype; } $return += $modlist[$course->id][$modname]; } } else { // Neither get_shortcuts() nor get_types() callbacks found, use the default item for the activity chooser. $modlist[$course->id][$modname][$modname] = $defaultmodule; $return[$modname] = $defaultmodule; } } core_collator::asort_objects_by_property($return, 'title'); return $return; }
/** * The list of block types that may be added to this page. * * @return array block name => record from block table. */ public function get_addable_blocks() { $this->check_is_loaded(); if (!is_null($this->addableblocks)) { return $this->addableblocks; } // Lazy load. $this->addableblocks = array(); $allblocks = blocks_get_record(); if (empty($allblocks)) { return $this->addableblocks; } $unaddableblocks = self::get_undeletable_block_types(); $requiredbythemeblocks = self::get_required_by_theme_block_types(); $pageformat = $this->page->pagetype; foreach ($allblocks as $block) { if (!($bi = block_instance($block->name))) { continue; } if ($block->visible && !in_array($block->name, $unaddableblocks) && !in_array($block->name, $requiredbythemeblocks) && ($bi->instance_allow_multiple() || !$this->is_block_present($block->name)) && blocks_name_allowed_in_format($block->name, $pageformat) && $bi->user_can_addto($this->page)) { $block->title = $bi->get_title(); $this->addableblocks[$block->name] = $block; } } core_collator::asort_objects_by_property($this->addableblocks, 'title'); return $this->addableblocks; }
require_capability('moodle/course:managegroups', $context); $strgroups = get_string('groups'); $strparticipants = get_string('participants'); $stroverview = get_string('overview', 'group'); $strgrouping = get_string('grouping', 'group'); $strgroup = get_string('group', 'group'); $strnotingrouping = get_string('notingrouping', 'group'); $strfiltergroups = get_string('filtergroups', 'group'); $strnogroups = get_string('nogroups', 'group'); $strdescription = get_string('description'); // Get all groupings and sort them by formatted name. $groupings = $DB->get_records('groupings', array('courseid' => $courseid), 'name'); foreach ($groupings as $gid => $grouping) { $groupings[$gid]->formattedname = format_string($grouping->name, true, array('context' => $context)); } core_collator::asort_objects_by_property($groupings, 'formattedname'); $members = array(); foreach ($groupings as $grouping) { $members[$grouping->id] = array(); } $members[-1] = array(); //groups not in a grouping // Get all groups $groups = $DB->get_records('groups', array('courseid' => $courseid), 'name'); $params = array('courseid' => $courseid); if ($groupid) { $groupwhere = "AND g.id = :groupid"; $params['groupid'] = $groupid; } else { $groupwhere = ""; }
/** * Reorder observers to allow quick lookup of observer for each event. */ protected static function order_all_observers() { foreach (self::$allobservers as $classname => $observers) { \core_collator::asort_objects_by_property($observers, 'priority', \core_collator::SORT_NUMERIC); self::$allobservers[$classname] = array_reverse($observers); } }
/** * Import the provided tour JSON. * * @param string $json The tour configuration. * @return tour */ public static function import_tour_from_json($json) { $tourconfig = json_decode($json); // We do not use this yet - we may do in the future. unset($tourconfig->version); $steps = $tourconfig->steps; unset($tourconfig->steps); $tourconfig->id = null; $tourconfig->sortorder = null; $tour = tour::load_from_record($tourconfig, true); $tour->persist(true); // Ensure that steps are orderered by their sortorder. \core_collator::asort_objects_by_property($steps, 'sortorder', \core_collator::SORT_NUMERIC); foreach ($steps as $stepconfig) { $stepconfig->id = null; $stepconfig->tourid = $tour->get_id(); $step = step::load_from_record($stepconfig, true); $step->persist(true); } return $tour; }