MDL-30070 message: Optimised search for users over multiple courses
[moodle.git] / filter / data / filter.php
CommitLineData
350f973d
EL
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.
13//
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/>.
16
17/**
18 * This filter provides automatic linking to database activity entries
19 * when found inside every Moodle text.
20 *
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
25 */
26
27defined('MOODLE_INTERNAL') || die();
28
29/**
30 * Database activity filtering
31 */
32class filter_data extends moodle_text_filter {
33
34 public function filter($text, array $options = array()) {
35 global $CFG, $DB;
36
37 // Trivial-cache - keyed on $cachedcontextid
38 static $cachedcontextid;
39 static $contentlist;
40
41 static $nothingtodo;
42
43 // Try to get current course
44 if (!$courseid = get_courseid_from_context($this->context)) {
45 $courseid = 0;
46 }
47
48 // Initialise/invalidate our trivial cache if dealing with a different context
49 if (!isset($cachedcontextid) || $cachedcontextid !== $this->context->id) {
50 $cachedcontextid = $this->context->id;
51 $contentlist = array();
52 $nothingtodo = false;
53 }
54
55 if ($nothingtodo === true) {
56 return $text;
57 }
58
59 // Create a list of all the resources to search for. It may be cached already.
60 if (empty($contentlist)) {
61 $coursestosearch = $courseid ? array($courseid) : array(); // Add courseid if found
62 if (get_site()->id != $courseid) { // Add siteid if was not courseid
63 $coursestosearch[] = get_site()->id;
64 }
65 // We look for text field contents only if have autolink enabled (param1)
66 list ($coursesql, $params) = $DB->get_in_or_equal($coursestosearch);
67 $sql = 'SELECT dc.id AS contentid, dr.id AS recordid, dc.content AS content, d.id AS dataid
68 FROM {data} d
69 JOIN {data_fields} df ON df.dataid = d.id
70 JOIN {data_records} dr ON dr.dataid = d.id
71 JOIN {data_content} dc ON dc.fieldid = df.id AND dc.recordid = dr.id
72 WHERE d.course ' . $coursesql . '
73 AND df.type = \'text\'
89640514 74 AND ' . $DB->sql_compare_text('df.param1', 1) . " = '1'";
350f973d
EL
75
76 if (!$contents = $DB->get_records_sql($sql, $params)) {
77 $nothingtodo = true;
78 return $text;
79 }
80
81 foreach ($contents as $key => $content) {
82 // Trim empty or unlinkable concepts
83 $currentcontent = trim(strip_tags($content->content));
84 if (empty($currentcontent)) {
85 unset($contents[$key]);
86 continue;
87 } else {
88 $contents[$key]->content = $currentcontent;
89 }
90
91 // Rule out any small integers. See bug 1446
92 $currentint = intval($currentcontent);
93 if ($currentint && (strval($currentint) == $currentcontent) && $currentint < 1000) {
94 unset($contents[$key]);
95 }
96 }
97
98 if (empty($contents)) {
99 $nothingtodo = true;
100 return $text;
101 }
102
103 usort($contents, 'filter_data::sort_entries_by_length');
104
105 foreach ($contents as $content) {
106 $href_tag_begin = '<a class="data autolink dataid'.$content->dataid.'" title="'.$content->content.'" '.
107 'href="'.$CFG->wwwroot.'/mod/data/view.php?d='.$content->dataid.
108 '&amp;rid='.$content->recordid.'">';
109 $contentlist[] = new filterobject($content->content, $href_tag_begin, '</a>', false, true);
110 }
111
112 $contentlist = filter_remove_duplicates($contentlist); // Clean dupes
113 }
114 return filter_phrases($text, $contentlist); // Look for all these links in the text
115 }
116
117 private static function sort_entries_by_length($content0, $content1) {
118 $len0 = strlen($content0->content);
119 $len1 = strlen($content1->content);
120
121 if ($len0 < $len1) {
122 return 1;
123 } else if ($len0 > $len1) {
124 return -1;
125 } else {
126 return 0;
127 }
128 }
129}