MDL-50550 wiki: Added unit tests for mod_wiki_get_wikis_by_courses
[moodle.git] / tag / locallib.php
CommitLineData
6bfe7aac 1<?php
bcdcee90
GGC
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/>.
d3477228 16
48d56528 17
d3477228 18/**
bcdcee90 19 * Moodle tag local library - output functions
d3477228 20 *
bcdcee90
GGC
21 * @package core_tag
22 * @copyright 2007 Luiz Cruz <luiz.laydner@gmail.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
d3477228 24 */
25
bcdcee90
GGC
26require_once($CFG->dirroot.'/tag/lib.php');
27require_once($CFG->libdir.'/filelib.php');
28
d3477228 29/**
bcdcee90 30 * Prints or returns a HTML tag cloud with varying classes styles depending on the popularity and type of each tag.
d3477228 31 *
bcdcee90
GGC
32 * @package core_tag
33 * @access public
34 * @category tag
7dd764b8
JG
35 * @param array $tagset Array of tags to display
36 * @param int $nr_of_tags Limit for the number of tags to return/display, used if $tagset is null
bcdcee90 37 * @param bool $return if true the function will return the generated tag cloud instead of displaying it.
740c4ada 38 * @param string $sort (optional) selected sorting, default is alpha sort (name) also timemodified or popularity
bcdcee90 39 * @return string|null a HTML string or null if this function does the output
d3477228 40 */
740c4ada 41function tag_print_cloud($tagset=null, $nr_of_tags=150, $return=false, $sort='') {
f7ed2687 42 global $CFG, $DB;
456d32fd 43
43731030 44 $can_manage_tags = has_capability('moodle/tag:manage', context_system::instance());
d3477228 45
7dd764b8
JG
46 if (is_null($tagset)) {
47 // No tag set received, so fetch tags from database
48 if ( !$tagsincloud = $DB->get_records_sql('SELECT tg.rawname, tg.id, tg.name, tg.tagtype, COUNT(ti.id) AS count, tg.flag
49 FROM {tag_instance} ti JOIN {tag} tg ON tg.id = ti.tagid
50 WHERE ti.itemtype <> \'tag\'
51 GROUP BY tg.id, tg.rawname, tg.name, tg.flag, tg.tagtype
52 ORDER BY count DESC, tg.name ASC', null, 0, $nr_of_tags) ) {
53 $tagsincloud = array();
54 }
55 } else {
56 $tagsincloud = $tagset;
420c306e 57 }
d3477228 58
dae7b4f6 59 $tagkeys = array_keys($tagsincloud);
f6d7d5f5 60 if (!empty($tagkeys)) {
61 $firsttagkey = $tagkeys[0];
62 $maxcount = $tagsincloud[$firsttagkey]->count;
63 }
d3477228 64
4e6d0c94 65 $etags = array();
d3477228 66
dae7b4f6 67 foreach ($tagsincloud as $tag) {
68 $size = (int) (( $tag->count / $maxcount) * 20);
4e6d0c94 69 $tag->class = "$tag->tagtype s$size";
70 $etags[] = $tag;
d3477228 71 }
72
740c4ada
JG
73 // Set up sort global - used to pass sort type into tag_cloud_sort through usort() avoiding multiple sort functions.
74 // TODO make calling functions pass 'count' or 'timemodified' not 'popularity' or 'date'.
75 $oldsort = empty($CFG->tagsort) ? null : $CFG->tagsort;
76 if ($sort == 'popularity') {
77 $CFG->tagsort = 'count';
78 } else if ($sort == 'date') {
79 $CFG->tagsort = 'timemodified';
80 } else {
81 $CFG->tagsort = 'name';
82 }
dae7b4f6 83 usort($etags, "tag_cloud_sort");
740c4ada
JG
84 $CFG->tagsort = $oldsort;
85
4e6d0c94 86 $output = '';
87 $output .= "\n<ul class='tag_cloud inline-list'>\n";
88 foreach ($etags as $tag) {
d3477228 89 if ($tag->flag > 0 && $can_manage_tags) {
dae7b4f6 90 $tagname = '<span class="flagged-tag">'. tag_display_name($tag) .'</span>';
91 } else {
4e6d0c94 92 $tagname = tag_display_name($tag);
d3477228 93 }
94
5a620a8c 95 $link = $CFG->wwwroot .'/tag/index.php?tag='. rawurlencode($tag->name);
4e6d0c94 96 $output .= '<li><a href="'. $link .'" class="'. $tag->class .'" '.
97 'title="'. get_string('numberofentries', 'blog', $tag->count) .'">'.
98 $tagname .'</a></li> ';
d3477228 99 }
4e6d0c94 100 $output .= "\n</ul>\n";
d3477228 101
102 if ($return) {
103 return $output;
104 } else {
105 echo $output;
106 }
107}
108
4e6d0c94 109/**
bcdcee90
GGC
110 * This function is used by print_tag_cloud, to usort() the tags in the cloud. See php.net/usort for the parameters documentation.
111 * This was originally in blocks/blog_tags/block_blog_tags.php, named blog_tags_sort().
112 *
113 * @package core_tag
114 * @access private
115 * @param string $a Tag name to compare against $b
116 * @param string $b Tag name to compare against $a
117 * @return int The result of the comparison/validation 1, 0 or -1
4e6d0c94 118 */
119function tag_cloud_sort($a, $b) {
120 global $CFG;
121
122 if (empty($CFG->tagsort)) {
47b13a7b 123 $tagsort = 'name'; // by default, sort by name
4e6d0c94 124 } else {
125 $tagsort = $CFG->tagsort;
126 }
127
128 if (is_numeric($a->$tagsort)) {
129 return ($a->$tagsort == $b->$tagsort) ? 0 : ($a->$tagsort > $b->$tagsort) ? 1 : -1;
130 } elseif (is_string($a->$tagsort)) {
131 return strcmp($a->$tagsort, $b->$tagsort);
132 } else {
133 return 0;
134 }
135}
136
d3477228 137/**
138 * Prints a box with the description of a tag and its related tags
139 *
bcdcee90
GGC
140 * @package core_tag
141 * @access public
142 * @todo MDL-31149 create a system setting for $max_tags_displayed, instead of using an in code literal
143 * @param stdClass $tag_object
144 * @param bool $return if true the function will return the generated tag cloud instead of displaying it.
145 * @return string/null a HTML box showing a description of the tag object and it's relationsips or null if output is done directly
146 * in the function.
d3477228 147 */
148function tag_print_description_box($tag_object, $return=false) {
149
456d32fd 150 global $USER, $CFG, $OUTPUT;
d3477228 151
bcdcee90 152 $max_tags_displayed = 10;
b50d2245 153
d3477228 154 $tagname = tag_display_name($tag_object);
b50d2245 155 $related_tags = tag_get_related_tags($tag_object->id, TAG_RELATED_ALL, $max_tags_displayed+1); // this gets one more than we want
d3477228 156
157 $content = !empty($tag_object->description) || $related_tags;
158 $output = '';
159
160 if ($content) {
456d32fd 161 $output .= $OUTPUT->box_start('generalbox', 'tag-description');
d3477228 162 }
163
164 if (!empty($tag_object->description)) {
c213773d 165 $options = new stdClass();
d3477228 166 $options->para = false;
367a75fa 167 $options->overflowdiv = true;
43731030 168 $tag_object->description = file_rewrite_pluginfile_urls($tag_object->description, 'pluginfile.php', context_system::instance()->id, 'tag', 'description', $tag_object->id);
d3477228 169 $output .= format_text($tag_object->description, $tag_object->descriptionformat, $options);
170 }
171
172 if ($related_tags) {
b50d2245 173 $more_links = false;
174 if (count($related_tags) > $max_tags_displayed) {
175 array_pop($related_tags);
176 $more_links = true;
177 }
d3477228 178 $output .= '<br /><br /><strong>'. get_string('relatedtags', 'tag') .': </strong>'. tag_get_related_tags_csv($related_tags);
b50d2245 179 if ($more_links) {
180 $output .= ' ...';
181 }
d3477228 182 }
183
184 if ($content) {
456d32fd 185 $output .= $OUTPUT->box_end();
d3477228 186 }
187
188 if ($return) {
189 return $output;
190 } else {
191 echo $output;
192 }
193}
194
195/**
196 * Prints a box that contains the management links of a tag
197 *
bcdcee90
GGC
198 * @access public
199 * @param stdClass $tag_object
200 * @param bool $return if true the function will return the generated tag cloud instead of displaying it.
201 * @return string|null a HTML string or null if this function does the output
d3477228 202 */
203function tag_print_management_box($tag_object, $return=false) {
204
456d32fd 205 global $USER, $CFG, $OUTPUT;
d3477228 206
207 $tagname = tag_display_name($tag_object);
208 $output = '';
209
210 if (!isguestuser()) {
456d32fd 211 $output .= $OUTPUT->box_start('box','tag-management-box');
43731030 212 $systemcontext = context_system::instance();
d3477228 213 $links = array();
456d32fd 214
3627b0e3 215 // Add a link for users to add/remove this from their interests
0f039283 216 if (tag_record_tagged_with('user', $USER->id, $tag_object->name)) {
3627b0e3 217 $links[] = '<a href="'. $CFG->wwwroot .'/tag/user.php?action=removeinterest&amp;sesskey='. sesskey() .'&amp;tag='. rawurlencode($tag_object->name) .'">'. get_string('removetagfrommyinterests', 'tag', $tagname) .'</a>';
218 } else {
219 $links[] = '<a href="'. $CFG->wwwroot .'/tag/user.php?action=addinterest&amp;sesskey='. sesskey() .'&amp;tag='. rawurlencode($tag_object->name) .'">'. get_string('addtagtomyinterests', 'tag', $tagname) .'</a>';
d3477228 220 }
221
7dd764b8
JG
222 // Flag as inappropriate link. Only people with moodle/tag:flag capability.
223 if (has_capability('moodle/tag:flag', $systemcontext)) {
224 $links[] = '<a href="'. $CFG->wwwroot .'/tag/user.php?action=flaginappropriate&amp;sesskey='. sesskey() .'&amp;tag='. rawurlencode($tag_object->name) .'">'. get_string('flagasinappropriate', 'tag', rawurlencode($tagname)) .'</a>';
225 }
3627b0e3 226
227 // Edit tag: Only people with moodle/tag:edit capability who either have it as an interest or can manage tags
456d32fd 228 if (has_capability('moodle/tag:edit', $systemcontext) ||
3efae234 229 has_capability('moodle/tag:manage', $systemcontext)) {
d3477228 230 $links[] = '<a href="'. $CFG->wwwroot .'/tag/edit.php?tag='. rawurlencode($tag_object->name) .'">'. get_string('edittag', 'tag') .'</a>';
231 }
232
d3477228 233 $output .= implode(' | ', $links);
456d32fd 234 $output .= $OUTPUT->box_end();
d3477228 235 }
236
237 if ($return) {
238 return $output;
239 } else {
240 echo $output;
241 }
242}
243
244/**
245 * Prints the tag search box
246 *
bcdcee90
GGC
247 * @access public
248 * @param bool $return if true return html string
249 * @return string|null a HTML string or null if this function does the output
d3477228 250 */
251function tag_print_search_box($return=false) {
456d32fd 252 global $CFG, $OUTPUT;
d3477228 253
456d32fd 254 $output = $OUTPUT->box_start('','tag-search-box');
d3477228 255 $output .= '<form action="'.$CFG->wwwroot.'/tag/search.php" style="display:inline">';
256 $output .= '<div>';
68134e44 257 $output .= '<label class="accesshide" for="searchform_search">'.get_string('searchtags', 'tag').'</label>';
d3477228 258 $output .= '<input id="searchform_search" name="query" type="text" size="40" />';
259 $output .= '<button id="searchform_button" type="submit">'. get_string('search', 'tag') .'</button><br />';
260 $output .= '</div>';
261 $output .= '</form>';
456d32fd 262 $output .= $OUTPUT->box_end();
d3477228 263
264 if ($return) {
265 return $output;
266 }
267 else {
268 echo $output;
269 }
270}
271
272/**
273 * Prints the tag search results
274 *
bcdcee90
GGC
275 * @access public
276 * @param string $query text that tag names will be matched against
277 * @param int $page current page
278 * @param int $perpage nr of users displayed per page
279 * @param bool $return if true return html string
280 * @return string|null a HTML string or null if this function does the output
d3477228 281 */
282function tag_print_search_results($query, $page, $perpage, $return=false) {
283
73aec3a7 284 global $CFG, $USER, $OUTPUT;
d3477228 285
7c2cc9c8
PS
286 $norm = tag_normalize($query, TAG_CASE_ORIGINAL);
287 $query = array_shift($norm);
0f039283 288
289 $count = sizeof(tag_find_tags($query, false));
d3477228 290 $tags = array();
291
0f039283 292 if ( $found_tags = tag_find_tags($query, true, $page * $perpage, $perpage) ) {
d3477228 293 $tags = array_values($found_tags);
294 }
295
296 $baseurl = $CFG->wwwroot.'/tag/search.php?query='. rawurlencode($query);
297 $output = '';
298
299 // link "Add $query to my interests"
300 $addtaglink = '';
0f039283 301 if( !tag_record_tagged_with('user', $USER->id, $query) ) {
3627b0e3 302 $addtaglink = '<a href="'. $CFG->wwwroot .'/tag/user.php?action=addinterest&amp;sesskey='. sesskey() .'&amp;tag='. rawurlencode($query) .'">';
0f039283 303 $addtaglink .= get_string('addtagtomyinterests', 'tag', htmlspecialchars($query)) .'</a>';
d3477228 304 }
305
306 if ( !empty($tags) ) { // there are results to display!!
73aec3a7 307 $output .= $OUTPUT->heading(get_string('searchresultsfor', 'tag', htmlspecialchars($query)) ." : {$count}", 3, 'main');
d3477228 308
309 //print a link "Add $query to my interests"
310 if (!empty($addtaglink)) {
456d32fd 311 $output .= $OUTPUT->box($addtaglink, 'box', 'tag-management-box');
d3477228 312 }
313
314 $nr_of_lis_per_ul = 6;
315 $nr_of_uls = ceil( sizeof($tags) / $nr_of_lis_per_ul );
316
317 $output .= '<ul id="tag-search-results">';
318 for($i = 0; $i < $nr_of_uls; $i++) {
319 $output .= '<li>';
320 foreach (array_slice($tags, $i * $nr_of_lis_per_ul, $nr_of_lis_per_ul) as $tag) {
321 $tag_link = ' <a href="'. $CFG->wwwroot .'/tag/index.php?id='. $tag->id .'">'. tag_display_name($tag) .'</a>';
322 $output .= '&#8226;'. $tag_link .'<br/>';
323 }
324 $output .= '</li>';
325 }
326 $output .= '</ul>';
327 $output .= '<div>&nbsp;</div>'; // <-- small layout hack in order to look good in Firefox
328
929d7a83 329 $output .= $OUTPUT->paging_bar($count, $page, $perpage, $baseurl);
d3477228 330 }
331 else { //no results were found!!
73aec3a7 332 $output .= $OUTPUT->heading(get_string('noresultsfor', 'tag', htmlspecialchars($query)), 3, 'main');
d3477228 333
334 //print a link "Add $query to my interests"
335 if (!empty($addtaglink)) {
456d32fd 336 $output .= $OUTPUT->box($addtaglink, 'box', 'tag-management-box');
d3477228 337 }
338 }
339
340 if ($return) {
341 return $output;
342 }
343 else {
344 echo $output;
345 }
346}
347
348/**
349 * Prints a table of the users tagged with the tag passed as argument
350 *
bcdcee90
GGC
351 * @param int $tag_object the tag we wish to return data for
352 * @param int $limitfrom (optional, required if $limitnum is set) prints users starting at this point.
353 * @param int $limitnum (optional, required if $limitfrom is set) prints this many users.
354 * @param bool $return if true return html string
355 * @return string|null a HTML string or null if this function does the output
d3477228 356 */
bcdcee90 357function tag_print_tagged_users_table($tag_object, $limitfrom='', $limitnum='', $return=false) {
d3477228 358
359 //List of users with this tag
2dc038ff 360 $userlist = tag_find_records($tag_object->name, 'user', $limitfrom, $limitnum);
d3477228 361
362 $output = tag_print_user_list($userlist, true);
363
364 if ($return) {
365 return $output;
366 }
367 else {
368 echo $output;
369 }
370}
371
372/**
373 * Prints an individual user box
374 *
bcdcee90
GGC
375 * @param user_object $user (contains the following fields: id, firstname, lastname and picture)
376 * @param bool $return if true return html string
377 * @return string|null a HTML string or null if this function does the output
d3477228 378 */
379function tag_print_user_box($user, $return=false) {
456d32fd 380 global $CFG, $OUTPUT;
d3477228 381
43731030 382 $usercontext = context_user::instance($user->id);
d3477228 383 $profilelink = '';
384
368f5b7b 385 if ($usercontext and (has_capability('moodle/user:viewdetails', $usercontext) || has_coursecontact_role($user->id))) {
d3477228 386 $profilelink = $CFG->wwwroot .'/user/view.php?id='. $user->id;
387 }
388
456d32fd 389 $output = $OUTPUT->box_start('user-box', 'user'. $user->id);
d3477228 390 $fullname = fullname($user);
391 $alt = '';
392
393 if (!empty($profilelink)) {
394 $output .= '<a href="'. $profilelink .'">';
395 $alt = $fullname;
396 }
397
8d6385d3 398 $output .= $OUTPUT->user_picture($user, array('size'=>100));
d3477228 399 $output .= '<br />';
400
401 if (!empty($profilelink)) {
402 $output .= '</a>';
403 }
404
405 //truncate name if it's too big
2f1e464a
PS
406 if (core_text::strlen($fullname) > 26) {
407 $fullname = core_text::substr($fullname, 0, 26) .'...';
d3477228 408 }
409
410 $output .= '<strong>'. $fullname .'</strong>';
456d32fd 411 $output .= $OUTPUT->box_end();
d3477228 412
413 if ($return) {
414 return $output;
415 }
416 else {
417 echo $output;
418 }
419}
bcdcee90 420
d3477228 421/**
422 * Prints a list of users
423 *
bcdcee90
GGC
424 * @param array $userlist an array of user objects
425 * @param bool $return if true return html string, otherwise output the result
426 * @return string|null a HTML string or null if this function does the output
d3477228 427 */
428function tag_print_user_list($userlist, $return=false) {
429
430 $output = '<ul class="inline-list">';
431
432 foreach ($userlist as $user){
433 $output .= '<li>'. tag_print_user_box($user, true) ."</li>\n";
434 }
435 $output .= "</ul>\n";
436
437 if ($return) {
438 return $output;
439 }
440 else {
441 echo $output;
442 }
443}