Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?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/>./*** Entry caching for glossary filter.** @package mod_glossary* @copyright 2014 Petr Skoda* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/namespace mod_glossary\local;defined('MOODLE_INTERNAL') || die();/*** Concept caching for glossary filter.** @package mod_glossary* @copyright 2014 Petr Skoda* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class concept_cache {/*** Event observer, do not call directly.* @param \core\event\course_module_updated $event*/public static function cm_updated(\core\event\course_module_updated $event) {if ($event->other['modulename'] !== 'glossary') {return;}// We do not know what changed exactly, so let's reset everything that might be affected.concept_cache::reset_course_muc($event->courseid);concept_cache::reset_global_muc();}/*** Reset concept related caches.* @param bool $phpunitreset*/public static function reset_caches($phpunitreset = false) {if ($phpunitreset) {return;}$cache = \cache::make('mod_glossary', 'concepts');$cache->purge();}/*** Reset the cache for course concepts.* @param int $courseid*/public static function reset_course_muc($courseid) {if (empty($courseid)) {return;}$cache = \cache::make('mod_glossary', 'concepts');$cache->delete((int)$courseid);}/*** Reset the cache for global concepts.*/public static function reset_global_muc() {$cache = \cache::make('mod_glossary', 'concepts');$cache->delete(0);}/*** Utility method to purge caches related to given glossary.* @param \stdClass $glossary*/public static function reset_glossary($glossary) {if (!$glossary->usedynalink) {return;}self::reset_course_muc($glossary->course);if ($glossary->globalglossary) {self::reset_global_muc();}}/*** Fetch concepts for given glossaries.* @param int[] $glossaries* @return array*/protected static function fetch_concepts(array $glossaries) {global $DB;$glossarylist = implode(',', $glossaries);$sql = "SELECT id, glossaryid, concept, casesensitive, 0 AS category, fullmatchFROM {glossary_entries}WHERE glossaryid IN ($glossarylist) AND usedynalink = 1 AND approved = 1UNIONSELECT id, glossaryid, name AS concept, 1 AS casesensitive, 1 AS category, 1 AS fullmatchFROM {glossary_categories}WHERE glossaryid IN ($glossarylist) AND usedynalink = 1UNIONSELECT ge.id, ge.glossaryid, ga.alias AS concept, ge.casesensitive, 0 AS category, ge.fullmatchFROM {glossary_alias} gaJOIN {glossary_entries} ge ON (ga.entryid = ge.id)WHERE ge.glossaryid IN ($glossarylist) AND ge.usedynalink = 1 AND ge.approved = 1";$concepts = array();$rs = $DB->get_recordset_sql($sql);foreach ($rs as $concept) {$currentconcept = trim(strip_tags($concept->concept));// Concept must be HTML-escaped, so do the same as format_string to turn ampersands into &.$currentconcept = replace_ampersands_not_followed_by_entity($currentconcept);if (empty($currentconcept)) {continue;}// Rule out any small integers, see MDL-1446.if (is_number($currentconcept) and $currentconcept < 1000) {continue;}$concept->concept = $currentconcept;$concepts[$concept->glossaryid][] = $concept;}$rs->close();return $concepts;}/*** Get all linked concepts from course.* @param int $courseid* @return array*/protected static function get_course_concepts($courseid) {global $DB;if (empty($courseid)) {return array(array(), array());}$courseid = (int)$courseid;// Get info on any glossaries in this course.$modinfo = get_fast_modinfo($courseid);$cminfos = $modinfo->get_instances_of('glossary');if (!$cminfos) {// No glossaries in this course, so don't do any work.return array(array(), array());}$cache = \cache::make('mod_glossary', 'concepts');$data = $cache->get($courseid);if (is_array($data)) {list($glossaries, $allconcepts) = $data;} else {// Find all course glossaries.$sql = "SELECT g.id, g.nameFROM {glossary} gJOIN {course_modules} cm ON (cm.instance = g.id)JOIN {modules} m ON (m.name = 'glossary' AND m.id = cm.module)WHERE g.usedynalink = 1 AND g.course = :course AND cm.visible = 1 AND m.visible = 1ORDER BY g.globalglossary, g.id";$glossaries = $DB->get_records_sql_menu($sql, array('course' => $courseid));if (!$glossaries) {$data = array(array(), array());$cache->set($courseid, $data);return $data;}foreach ($glossaries as $id => $name) {$name = str_replace(':', '-', $name);$glossaries[$id] = replace_ampersands_not_followed_by_entity(strip_tags($name));}$allconcepts = self::fetch_concepts(array_keys($glossaries));foreach ($glossaries as $gid => $unused) {if (!isset($allconcepts[$gid])) {unset($glossaries[$gid]);}}if (!$glossaries) {// This means there are no interesting concepts in the existing glossaries.$data = array(array(), array());$cache->set($courseid, $data);return $data;}$cache->set($courseid, array($glossaries, $allconcepts));}$concepts = $allconcepts;// Verify access control to glossary instances.foreach ($concepts as $modid => $unused) {if (!isset($cminfos[$modid])) {// This should not happen.unset($concepts[$modid]);unset($glossaries[$modid]);continue;}if (!$cminfos[$modid]->uservisible) {unset($concepts[$modid]);unset($glossaries[$modid]);continue;}}return array($glossaries, $concepts);}/*** Get all linked global concepts.* @return array*/protected static function get_global_concepts() {global $DB;$cache = \cache::make('mod_glossary', 'concepts');$data = $cache->get(0);if (is_array($data)) {list($glossaries, $allconcepts) = $data;} else {// Find all global glossaries - no access control here.$sql = "SELECT g.id, g.nameFROM {glossary} gJOIN {course_modules} cm ON (cm.instance = g.id)JOIN {modules} m ON (m.name = 'glossary' AND m.id = cm.module)WHERE g.usedynalink = 1 AND g.globalglossary = 1 AND cm.visible = 1 AND m.visible = 1ORDER BY g.globalglossary, g.id";$glossaries = $DB->get_records_sql_menu($sql);if (!$glossaries) {$data = array(array(), array());$cache->set(0, $data);return $data;}foreach ($glossaries as $id => $name) {$name = str_replace(':', '-', $name);$glossaries[$id] = replace_ampersands_not_followed_by_entity(strip_tags($name));}$allconcepts = self::fetch_concepts(array_keys($glossaries));foreach ($glossaries as $gid => $unused) {if (!isset($allconcepts[$gid])) {unset($glossaries[$gid]);}}$cache->set(0, array($glossaries, $allconcepts));}// NOTE: no access control is here because it would be way too expensive to check access// to all courses that contain the global glossaries.return array($glossaries, $allconcepts);}/*** Get all concepts that should be linked in the given course.* @param int $courseid* @return array with two elements - array of glossaries and concepts for each glossary*/public static function get_concepts($courseid) {list($glossaries, $concepts) = self::get_course_concepts($courseid);list($globalglossaries, $globalconcepts) = self::get_global_concepts();foreach ($globalconcepts as $gid => $cs) {if (!isset($concepts[$gid])) {$concepts[$gid] = $cs;}}foreach ($globalglossaries as $gid => $name) {if (!isset($glossaries[$gid])) {$glossaries[$gid] = $name;}}return array($glossaries, $concepts);}}