MDL-67468 filter_activitynames: use MUC
[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 {
35     function filter($text, array $options = array()) {
36         $coursectx = $this->context->get_course_context(false);
37         if (!$coursectx) {
38             return $text;
39         }
40         $courseid = $coursectx->instanceid;
42         $activitylist = $this->get_cached_activity_list($courseid);
44         $filterslist = array();
45         if (!empty($activitylist)) {
46             $cmid = $this->context->instanceid;
47             if ($this->context->contextlevel == CONTEXT_MODULE && isset($activitylist[$cmid])) {
48                 // remove filterobjects for the current module
49                 $filterslist = array_values(array_diff_key($activitylist, array($cmid => 1, $cmid.'-e' => 1)));
50             } else {
51                 $filterslist = array_values($activitylist);
52             }
53         }
55         if ($filterslist) {
56             return $text = filter_phrases($text, $filterslist);
57         } else {
58             return $text;
59         }
60     }
62     /**
63      * Get all the cached activity list for a course
64      *
65      * @param int $courseid id of the course
66      * @return filterobject[] the activities
67      */
68     protected function get_cached_activity_list($courseid) {
69         global $USER;
70         $cached = cache::make_from_params(cache_store::MODE_REQUEST, 'filter', 'activitynames');
72         // Return cached activity list.
73         if ($cached->get('cachecourseid') == $courseid && $cached->get('cacheuserid') == $USER->id) {
74             return $cached->get('activitylist');
75         }
77         // Not cached yet, get activity list and set cache.
78         $activitylist = $this->get_activity_list($courseid);
79         $cached->set('cacheuserid', $USER->id);
80         $cached->set('cachecourseid', $courseid);
81         $cached->set('activitylist', $activitylist);
82         return $activitylist;
83     }
85     /**
86      * Get all the activity list for a course
87      *
88      * @param int $courseid id of the course
89      * @return filterobject[] the activities
90      */
91     protected function get_activity_list($courseid) {
92         $activitylist = array();
94         $modinfo = get_fast_modinfo($courseid);
95         if (!empty($modinfo->cms)) {
96             $activitylist = array(); // We will store all the created filters here.
98             // Create array of visible activities sorted by the name length (we are only interested in properties name and url).
99             $sortedactivities = array();
100             foreach ($modinfo->cms as $cm) {
101                 // Use normal access control and visibility, but exclude labels and hidden activities.
102                 if ($cm->visible and $cm->has_view() and $cm->uservisible) {
103                     $sortedactivities[] = (object)array(
104                         'name' => $cm->name,
105                         'url' => $cm->url,
106                         'id' => $cm->id,
107                         'namelen' => -strlen($cm->name), // Negative value for reverse sorting.
108                     );
109                 }
110             }
111             // Sort activities by the length of the activity name in reverse order.
112             core_collator::asort_objects_by_property($sortedactivities, 'namelen', core_collator::SORT_NUMERIC);
114             foreach ($sortedactivities as $cm) {
115                 $title = s(trim(strip_tags($cm->name)));
116                 $currentname = trim($cm->name);
117                 $entitisedname  = s($currentname);
118                 // Avoid empty or unlinkable activity names.
119                 if (!empty($title)) {
120                     $hreftagbegin = html_writer::start_tag('a',
121                         array('class' => 'autolink', 'title' => $title,
122                             'href' => $cm->url));
123                     $activitylist[$cm->id] = new filterobject($currentname, $hreftagbegin, '</a>', false, true);
124                     if ($currentname != $entitisedname) {
125                         // If name has some entity (&amp; &quot; &lt; &gt;) add that filter too. MDL-17545.
126                         $activitylist[$cm->id.'-e'] = new filterobject($entitisedname, $hreftagbegin, '</a>', false, true);
127                     }
128                 }
129             }
130         }
131         return $activitylist;
132     }