Merge branch 'MDL-31502-master-2' of git://git.luns.net.uk/moodle
[moodle.git] / filter / data / filter.php
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/>.
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  */
27 defined('MOODLE_INTERNAL') || die();
29 /**
30  * Database activity filtering
31  */
32 class filter_data extends moodle_text_filter {
34     public function filter($text, array $options = array()) {
35         global $CFG, $DB;
37         // Trivial-cache - keyed on $cachedcontextid
38         static $cachedcontextid;
39         static $contentlist;
41         static $nothingtodo;
43         // Try to get current course
44         if (!$courseid = get_courseid_from_context($this->context)) {
45             $courseid = 0;
46         }
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         }
55         if ($nothingtodo === true) {
56             return $text;
57         }
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\'
74                        AND ' . $DB->sql_compare_text('df.param1', 1) . ' = 1';
76             if (!$contents = $DB->get_records_sql($sql, $params)) {
77                 $nothingtodo = true;
78                 return $text;
79             }
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                 }
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             }
98             if (empty($contents)) {
99                 $nothingtodo = true;
100                 return $text;
101             }
103             usort($contents, 'filter_data::sort_entries_by_length');
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             }
112             $contentlist = filter_remove_duplicates($contentlist); // Clean dupes
113         }
114         return filter_phrases($text, $contentlist);  // Look for all these links in the text
115     }
117     private static function sort_entries_by_length($content0, $content1) {
118         $len0 = strlen($content0->content);
119         $len1 = strlen($content1->content);
121         if ($len0 < $len1) {
122             return 1;
123         } else if ($len0 > $len1) {
124             return -1;
125         } else {
126             return 0;
127         }
128     }