|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00028 defined('MOODLE_INTERNAL') || die(); 00029 00036 class filter_glossary extends moodle_text_filter { 00037 00038 public function filter($text, array $options = array()) { 00039 global $CFG, $DB, $GLOSSARY_EXCLUDECONCEPTS, $PAGE; 00040 00041 // Trivial-cache - keyed on $cachedcontextid 00042 static $cachedcontextid; 00043 static $conceptlist; 00044 00045 static $jsinitialised; // To control unique js init 00046 static $nothingtodo; // To avoid processing if no glossaries / concepts are found 00047 00048 // Try to get current course 00049 if (!$courseid = get_courseid_from_context($this->context)) { 00050 $courseid = 0; 00051 } 00052 00053 // Initialise/invalidate our trivial cache if dealing with a different context 00054 if (!isset($cachedcontextid) || $cachedcontextid !== $this->context->id) { 00055 $cachedcontextid = $this->context->id; 00056 $conceptlist = array(); 00057 $nothingtodo = false; 00058 } 00059 00060 if ($nothingtodo === true) { 00061 return $text; 00062 } 00063 00064 // Create a list of all the concepts to search for. It may be cached already. 00065 if (empty($conceptlist)) { 00066 00067 // Find all the glossaries we need to examine 00068 if (!$glossaries = $DB->get_records_sql_menu(' 00069 SELECT g.id, g.name 00070 FROM {glossary} g, {course_modules} cm, {modules} m 00071 WHERE m.name = \'glossary\' 00072 AND cm.module = m.id 00073 AND cm.visible = 1 00074 AND g.id = cm.instance 00075 AND g.usedynalink != 0 00076 AND (g.course = ? OR g.globalglossary = 1) 00077 ORDER BY g.globalglossary, g.id', array($courseid))) { 00078 $nothingtodo = true; 00079 return $text; 00080 } 00081 00082 // Make a list of glossary IDs for searching 00083 $glossarylist = implode(',', array_keys($glossaries)); 00084 00085 // Pull out all the raw data from the database for entries, categories and aliases 00086 $entries = $DB->get_records_select('glossary_entries', 00087 'glossaryid IN ('.$glossarylist.') AND usedynalink != 0 AND approved != 0 ', null, '', 00088 'id,glossaryid, concept, casesensitive, 0 AS category, fullmatch'); 00089 00090 $categories = $DB->get_records_select('glossary_categories', 00091 'glossaryid IN ('.$glossarylist.') AND usedynalink != 0', null, '', 00092 'id,glossaryid,name AS concept, 1 AS casesensitive, 1 AS category, 1 AS fullmatch'); 00093 00094 $aliases = $DB->get_records_sql(' 00095 SELECT ga.id, ge.id AS entryid, ge.glossaryid, 00096 ga.alias AS concept, ge.concept AS originalconcept, 00097 casesensitive, 0 AS category, fullmatch 00098 FROM {glossary_alias} ga, 00099 {glossary_entries} ge 00100 WHERE ga.entryid = ge.id 00101 AND ge.glossaryid IN ('.$glossarylist.') 00102 AND ge.usedynalink != 0 00103 AND ge.approved != 0', null); 00104 00105 // Combine them into one big list 00106 $concepts = array(); 00107 if ($entries and $categories) { 00108 $concepts = array_merge($entries, $categories); 00109 } else if ($categories) { 00110 $concepts = $categories; 00111 } else if ($entries) { 00112 $concepts = $entries; 00113 } 00114 00115 if ($aliases) { 00116 $concepts = array_merge($concepts, $aliases); 00117 } 00118 00119 if (!empty($concepts)) { 00120 foreach ($concepts as $key => $concept) { 00121 // Trim empty or unlinkable concepts 00122 $currentconcept = trim(strip_tags($concept->concept)); 00123 if (empty($currentconcept)) { 00124 unset($concepts[$key]); 00125 continue; 00126 } else { 00127 $concepts[$key]->concept = $currentconcept; 00128 } 00129 00130 // Rule out any small integers. See bug 1446 00131 $currentint = intval($currentconcept); 00132 if ($currentint && (strval($currentint) == $currentconcept) && $currentint < 1000) { 00133 unset($concepts[$key]); 00134 } 00135 } 00136 } 00137 00138 if (empty($concepts)) { 00139 $nothingtodo = true; 00140 return $text; 00141 } 00142 00143 usort($concepts, 'filter_glossary::sort_entries_by_length'); 00144 00145 $strcategory = get_string('category', 'glossary'); 00146 00147 // Loop through all the concepts, setting up our data structure for the filter 00148 $conceptlist = array(); // We will store all the concepts here 00149 00150 foreach ($concepts as $concept) { 00151 $glossaryname = str_replace(':', '-', $glossaries[$concept->glossaryid]); 00152 if ($concept->category) { // Link to a category 00153 // TODO: Fix this string usage 00154 $title = strip_tags($glossaryname.': '.$strcategory.' '.$concept->concept); 00155 $href_tag_begin = '<a class="glossary autolink category glossaryid'.$concept->glossaryid.'" title="'.$title.'" '. 00156 'href="'.$CFG->wwwroot.'/mod/glossary/view.php?g='.$concept->glossaryid. 00157 '&mode=cat&hook='.$concept->id.'">'; 00158 } else { // Link to entry or alias 00159 if (!empty($concept->originalconcept)) { // We are dealing with an alias (so show and point to original) 00160 $title = str_replace('"', "'", strip_tags($glossaryname.': '.$concept->originalconcept)); 00161 $concept->id = $concept->entryid; 00162 } else { // This is an entry 00163 $title = str_replace('"', "'", strip_tags($glossaryname.': '.$concept->concept)); 00164 } 00165 // hardcoding dictionary format in the URL rather than defaulting 00166 // to the current glossary format which may not work in a popup. 00167 // for example "entry list" means the popup would only contain 00168 // a link that opens another popup. 00169 $link = new moodle_url('/mod/glossary/showentry.php', array('courseid'=>$courseid, 'eid'=>$concept->id, 'displayformat'=>'dictionary')); 00170 $attributes = array( 00171 'href' => $link, 00172 'title'=> $title, 00173 'class'=> 'glossary autolink concept glossaryid'.$concept->glossaryid); 00174 00175 // this flag is optionally set by resource_pluginfile() 00176 // if processing an embedded file use target to prevent getting nested Moodles 00177 if (isset($CFG->embeddedsoforcelinktarget) && $CFG->embeddedsoforcelinktarget) { 00178 $attributes['target'] = '_top'; 00179 } 00180 00181 $href_tag_begin = html_writer::start_tag('a', $attributes); 00182 } 00183 $conceptlist[] = new filterobject($concept->concept, $href_tag_begin, '</a>', 00184 $concept->casesensitive, $concept->fullmatch); 00185 } 00186 00187 $conceptlist = filter_remove_duplicates($conceptlist); 00188 00189 if (empty($jsinitialised)) { 00190 // Add a JavaScript event to open popup's here. This only ever need to be 00191 // added once! 00192 $PAGE->requires->yui_module( 00193 'moodle-filter_glossary-autolinker', 00194 'M.filter_glossary.init_filter_autolinking', 00195 array(array('courseid' => $courseid))); 00196 $jsinitialised = true; 00197 } 00198 } 00199 00200 if (!empty($GLOSSARY_EXCLUDECONCEPTS)) { 00201 $reducedconceptlist=array(); 00202 foreach($conceptlist as $concept) { 00203 if(!in_array($concept->phrase,$GLOSSARY_EXCLUDECONCEPTS)) { 00204 $reducedconceptlist[]=$concept; 00205 } 00206 } 00207 return filter_phrases($text, $reducedconceptlist); 00208 } 00209 00210 return filter_phrases($text, $conceptlist); // Actually search for concepts! 00211 } 00212 00213 00214 private static function sort_entries_by_length($entry0, $entry1) { 00215 $len0 = strlen($entry0->concept); 00216 $len1 = strlen($entry1->concept); 00217 00218 if ($len0 < $len1) { 00219 return 1; 00220 } else if ($len0 > $len1) { 00221 return -1; 00222 } else { 00223 return 0; 00224 } 00225 } 00226 }