d9ce6f7655e94fc3236b0500830f2f39426095c7
[moodle.git] / filter / activitynames / filter.php
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
18 /**
19  * This filter provides automatic linking to
20  * activities when its name (title) is found inside every Moodle text
21  *
22  * @package    filter
23  * @subpackage activitynames
24  * @copyright  2004 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
25  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26  */
28 defined('MOODLE_INTERNAL') || die();
30 /**
31  * Activity name filtering
32  */
33 class filter_activitynames extends moodle_text_filter {
34     // Trivial-cache - keyed on $cachedcourseid and $cacheduserid.
35     static $activitylist = null;
36     static $cachedcourseid;
37     static $cacheduserid;
39     function filter($text, array $options = array()) {
40         global $USER; // Since 2.7 we can finally start using globals in filters.
42         $coursectx = $this->context->get_course_context(false);
43         if (!$coursectx) {
44             return $text;
45         }
46         $courseid = $coursectx->instanceid;
48         // Initialise/invalidate our trivial cache if dealing with a different course.
49         if (!isset(self::$cachedcourseid) || self::$cachedcourseid !== (int)$courseid) {
50             self::$activitylist = null;
51         }
52         self::$cachedcourseid = (int)$courseid;
53         // And the same for user id.
54         if (!isset(self::$cacheduserid) || self::$cacheduserid !== (int)$USER->id) {
55             self::$activitylist = null;
56         }
57         self::$cacheduserid = (int)$USER->id;
59         /// It may be cached
61         if (is_null(self::$activitylist)) {
62             self::$activitylist = array();
64             $modinfo = get_fast_modinfo($courseid);
65             if (!empty($modinfo->cms)) {
66                 self::$activitylist = array(); // We will store all the created filters here.
68                 // Create array of visible activities sorted by the name length (we are only interested in properties name and url).
69                 $sortedactivities = array();
70                 foreach ($modinfo->cms as $cm) {
71                     // Use normal access control and visibility, but exclude labels and hidden activities.
72                     if ($cm->visible and $cm->has_view() and $cm->uservisible) {
73                         $sortedactivities[] = (object)array(
74                             'name' => $cm->name,
75                             'url' => $cm->url,
76                             'id' => $cm->id,
77                             'namelen' => -strlen($cm->name), // Negative value for reverse sorting.
78                         );
79                     }
80                 }
81                 // Sort activities by the length of the activity name in reverse order.
82                 core_collator::asort_objects_by_property($sortedactivities, 'namelen', core_collator::SORT_NUMERIC);
84                 foreach ($sortedactivities as $cm) {
85                     $title = s(trim(strip_tags($cm->name)));
86                     $currentname = trim($cm->name);
87                     $entitisedname  = s($currentname);
88                     // Avoid empty or unlinkable activity names.
89                     if (!empty($title)) {
90                         $href_tag_begin = html_writer::start_tag('a',
91                                 array('class' => 'autolink', 'title' => $title,
92                                     'href' => $cm->url));
93                         self::$activitylist[$cm->id] = new filterobject($currentname, $href_tag_begin, '</a>', false, true);
94                         if ($currentname != $entitisedname) {
95                             // If name has some entity (&amp; &quot; &lt; &gt;) add that filter too. MDL-17545.
96                             self::$activitylist[$cm->id.'-e'] = new filterobject($entitisedname, $href_tag_begin, '</a>', false, true);
97                         }
98                     }
99                 }
100             }
101         }
103         $filterslist = array();
104         if (self::$activitylist) {
105             $cmid = $this->context->instanceid;
106             if ($this->context->contextlevel == CONTEXT_MODULE && isset(self::$activitylist[$cmid])) {
107                 // remove filterobjects for the current module
108                 $filterslist = array_values(array_diff_key(self::$activitylist, array($cmid => 1, $cmid.'-e' => 1)));
109             } else {
110                 $filterslist = array_values(self::$activitylist);
111             }
112         }
114         if ($filterslist) {
115             return $text = filter_phrases($text, $filterslist);
116         } else {
117             return $text;
118         }
119     }