Merge branch 'MDL-36754-master' of git://github.com/andrewnicols/moodle
[moodle.git] / filter / data / filter.php
blob4eabac05c3647032555219ebe03c1238d13b2445
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 /**
18 * This filter provides automatic linking to database activity entries
19 * when found inside every Moodle text.
21 * @package filter
22 * @subpackage data
23 * @copyright 2006 Vy-Shane Sin Fat
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 defined('MOODLE_INTERNAL') || die();
29 /**
30 * Database activity filtering
32 class filter_data extends moodle_text_filter {
34 public function filter($text, array $options = array()) {
35 global $CFG, $DB, $USER;
37 // Trivial-cache - keyed on $cachedcourseid + $cacheduserid.
38 static $cachedcourseid = null;
39 static $cacheduserid = null;
40 static $coursecontentlist = array();
41 static $sitecontentlist = array();
43 static $nothingtodo;
45 // Try to get current course.
46 $coursectx = $this->context->get_course_context(false);
47 if (!$coursectx) {
48 // We could be in a course category so no entries for courseid == 0 will be found.
49 $courseid = 0;
50 } else {
51 $courseid = $coursectx->instanceid;
54 if ($cacheduserid !== $USER->id) {
55 // Invalidate all caches if the user changed.
56 $coursecontentlist = array();
57 $sitecontentlist = array();
58 $cacheduserid = $USER->id;
59 $cachedcourseid = $courseid;
60 $nothingtodo = false;
61 } else if ($courseid != get_site()->id && $courseid != 0 && $cachedcourseid != $courseid) {
62 // Invalidate course-level caches if the course id changed.
63 $coursecontentlist = array();
64 $cachedcourseid = $courseid;
65 $nothingtodo = false;
68 if ($nothingtodo === true) {
69 return $text;
72 // If courseid == 0 only site entries will be returned.
73 if ($courseid == get_site()->id || $courseid == 0) {
74 $contentlist = & $sitecontentlist;
75 } else {
76 $contentlist = & $coursecontentlist;
79 // Create a list of all the resources to search for. It may be cached already.
80 if (empty($contentlist)) {
81 $coursestosearch = $courseid ? array($courseid) : array(); // Add courseid if found
82 if (get_site()->id != $courseid) { // Add siteid if was not courseid
83 $coursestosearch[] = get_site()->id;
85 // We look for text field contents only if have autolink enabled (param1)
86 list ($coursesql, $params) = $DB->get_in_or_equal($coursestosearch);
87 $sql = 'SELECT dc.id AS contentid, dr.id AS recordid, dc.content AS content, d.id AS dataid
88 FROM {data} d
89 JOIN {data_fields} df ON df.dataid = d.id
90 JOIN {data_records} dr ON dr.dataid = d.id
91 JOIN {data_content} dc ON dc.fieldid = df.id AND dc.recordid = dr.id
92 WHERE d.course ' . $coursesql . '
93 AND df.type = \'text\'
94 AND ' . $DB->sql_compare_text('df.param1', 1) . " = '1'";
96 if (!$contents = $DB->get_records_sql($sql, $params)) {
97 $nothingtodo = true;
98 return $text;
101 foreach ($contents as $key => $content) {
102 // Trim empty or unlinkable concepts
103 $currentcontent = trim(strip_tags($content->content));
104 if (empty($currentcontent)) {
105 unset($contents[$key]);
106 continue;
107 } else {
108 $contents[$key]->content = $currentcontent;
111 // Rule out any small integers. See bug 1446
112 $currentint = intval($currentcontent);
113 if ($currentint && (strval($currentint) == $currentcontent) && $currentint < 1000) {
114 unset($contents[$key]);
118 if (empty($contents)) {
119 $nothingtodo = true;
120 return $text;
123 usort($contents, 'filter_data::sort_entries_by_length');
125 foreach ($contents as $content) {
126 $href_tag_begin = '<a class="data autolink dataid'.$content->dataid.'" title="'.$content->content.'" '.
127 'href="'.$CFG->wwwroot.'/mod/data/view.php?d='.$content->dataid.
128 '&amp;rid='.$content->recordid.'">';
129 $contentlist[] = new filterobject($content->content, $href_tag_begin, '</a>', false, true);
132 $contentlist = filter_remove_duplicates($contentlist); // Clean dupes
134 return filter_phrases($text, $contentlist); // Look for all these links in the text
137 private static function sort_entries_by_length($content0, $content1) {
138 $len0 = strlen($content0->content);
139 $len1 = strlen($content1->content);
141 if ($len0 < $len1) {
142 return 1;
143 } else if ($len0 > $len1) {
144 return -1;
145 } else {
146 return 0;