MDL-21781 removing user from cohorts during delete
[moodle.git] / mod / glossary / lib.php
CommitLineData
e121db76 1<?php
07842023 2
e121db76 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/>.
17
18/**
19 * Library of functions and constants for module glossary
20 * (replace glossary with the name of your module and delete this line)
21 *
22 * @package mod-glossary
23 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
07842023 26
214b1cf7 27
7dd88447 28define("GLOSSARY_SHOW_ALL_CATEGORIES", 0);
29define("GLOSSARY_SHOW_NOT_CATEGORISED", -1);
c76e673a 30
1ac87c73 31define("GLOSSARY_NO_VIEW", -1);
7dd88447 32define("GLOSSARY_STANDARD_VIEW", 0);
33define("GLOSSARY_CATEGORY_VIEW", 1);
c197e607 34define("GLOSSARY_DATE_VIEW", 2);
1ac87c73 35define("GLOSSARY_AUTHOR_VIEW", 3);
36define("GLOSSARY_ADDENTRY_VIEW", 4);
37define("GLOSSARY_IMPORT_VIEW", 5);
38define("GLOSSARY_EXPORT_VIEW", 6);
39define("GLOSSARY_APPROVAL_VIEW", 7);
fb443f1a 40
da9c60ec 41/// STANDARD FUNCTIONS ///////////////////////////////////////////////////////////
e121db76 42/**
43 * @global object
44 * @param object $glossary
45 * @return int
46 */
07842023 47function glossary_add_instance($glossary) {
c18269c7 48 global $DB;
07842023 49/// Given an object containing all the necessary data,
7cac0c4b 50/// (defined by the form in mod_form.php) this function
07842023 51/// will create a new instance and return the id number
52/// of the new instance.
53
63e21b9b 54 if (empty($glossary->userating)) {
63dd5fb2 55 $glossary->assessed = 0;
56 }
57
e6d45048 58 if (empty($glossary->ratingtime) or empty($glossary->assessed)) {
63dd5fb2 59 $glossary->assesstimestart = 0;
60 $glossary->assesstimefinish = 0;
61 }
62
63e21b9b 63 if (empty($glossary->globalglossary) ) {
0de786f7 64 $glossary->globalglossary = 0;
63e21b9b 65 }
66
957f6fc9 67 if (!has_capability('mod/glossary:manageentries', get_context_instance(CONTEXT_SYSTEM))) {
0de786f7 68 $glossary->globalglossary = 0;
69 }
70
e6d45048 71 $glossary->timecreated = time();
07842023 72 $glossary->timemodified = $glossary->timecreated;
73
ff424012 74 //Check displayformat is a valid one
75 $formats = get_list_of_plugins('mod/glossary/formats','TEMPLATE');
76 if (!in_array($glossary->displayformat, $formats)) {
5973a4c4 77 print_error('unknowformat', '', '', $glossary->displayformat);
a02c77dc 78 }
24c1be88 79
2a7eff41 80 $returnid = $DB->insert_record("glossary", $glossary);
81 $glossary->id = $returnid;
82 glossary_grade_item_update($glossary);
e6d45048 83
84 return $returnid;
07842023 85}
86
e121db76 87/**
88 * Given an object containing all the necessary data,
89 * (defined by the form in mod_form.php) this function
90 * will update an existing instance with new data.
91 *
92 * @global object
93 * @global object
94 * @param object $glossary
95 * @return bool
96 */
07842023 97function glossary_update_instance($glossary) {
c18269c7 98 global $CFG, $DB;
a02c77dc 99
da5754f8 100 if (empty($glossary->globalglossary)) {
101 $glossary->globalglossary = 0;
102 }
0de786f7 103
957f6fc9 104 if (!has_capability('mod/glossary:manageentries', get_context_instance(CONTEXT_SYSTEM))) {
63e21b9b 105 // keep previous
106 unset($glossary->globalglossary);
107 }
108
07842023 109 $glossary->timemodified = time();
e6d45048 110 $glossary->id = $glossary->instance;
07842023 111
63e87951
AD
112 //if (empty($glossary->userating)) {
113// $glossary->assessed = 0;
114 // }
63dd5fb2 115
e6d45048 116 if (empty($glossary->ratingtime) or empty($glossary->assessed)) {
63dd5fb2 117 $glossary->assesstimestart = 0;
118 $glossary->assesstimefinish = 0;
119 }
120
ff424012 121 //Check displayformat is a valid one
122 $formats = get_list_of_plugins('mod/glossary/formats','TEMPLATE');
123 if (!in_array($glossary->displayformat, $formats)) {
5973a4c4 124 print_error('unknowformat', '', '', $glossary->displayformat);
ff424012 125 }
126
2a7eff41 127 $return = $DB->update_record("glossary", $glossary);
128 if ($glossary->defaultapproval) {
129 $DB->execute("UPDATE {glossary_entries} SET approved = 1 where approved <> 1 and glossaryid = ?", array($glossary->id));
5eaa2d34 130 }
2a7eff41 131 glossary_grade_item_update($glossary);
07842023 132
5eaa2d34 133 return $return;
07842023 134}
135
49bcd737 136/**
137 * Given an ID of an instance of this module,
138 * this function will permanently delete the instance
139 * and any data that depends on it.
e121db76 140 *
141 * @global object
49bcd737 142 * @param int $id glossary id
143 * @return bool success
144 */
07842023 145function glossary_delete_instance($id) {
c18269c7 146 global $DB;
07842023 147
49bcd737 148 if (!$glossary = $DB->get_record('glossary', array('id'=>$id))) {
07842023 149 return false;
150 }
151
49bcd737 152 if (!$cm = get_coursemodule_from_instance('glossary', $id)) {
153 return false;
154 }
07842023 155
49bcd737 156 if (!$context = get_context_instance(CONTEXT_MODULE, $cm->id)) {
157 return false;
158 }
07842023 159
49bcd737 160 $fs = get_file_storage();
161
162 if ($glossary->mainglossary) {
163 // unexport entries
164 $sql = "SELECT ge.id, ge.sourceglossaryid, cm.id AS sourcecmid
165 FROM {glossary_entries} ge
166 JOIN {modules} m ON m.name = 'glossary'
167 JOIN {course_modules} cm ON (cm.module = m.id AND cm.instance = ge.sourceglossaryid)
168 WHERE ge.glossaryid = ? AND ge.sourceglossaryid > 0";
169
170 if ($exported = $DB->get_records_sql($sql, array($id))) {
171 foreach ($exported as $entry) {
172 $entry->glossaryid = $entry->sourceglossaryid;
173 $entry->sourceglossaryid = 0;
174 $newcontext = get_context_instance(CONTEXT_MODULE, $entry->sourcecmid);
175 if ($oldfiles = $fs->get_area_files($context->id, 'glossary_attachment', $entry->id)) {
176 foreach ($oldfiles as $oldfile) {
177 $file_record = new object();
178 $file_record->contextid = $newcontext->id;
179 $fs->create_file_from_storedfile($file_record, $oldfile);
180 }
181 $fs->delete_area_files($context->id, 'glossary_attachment', $entry->id);
182 $entry->attachment = '1';
072f7533 183 } else {
49bcd737 184 $entry->attachment = '0';
072f7533 185 }
49bcd737 186 $DB->update_record('glossary_entries', $entry);
49210b90 187 }
188 }
49bcd737 189 } else {
190 // move exported entries to main glossary
191 $sql = "UPDATE {glossary_entries}
192 SET sourceglossaryid = 0
193 WHERE sourceglossaryid = ?";
194 $DB->execute($sql, array($id));
07842023 195 }
49bcd737 196
197 // Delete any dependent records
198 $entry_select = "SELECT id FROM {glossary_entries} WHERE glossaryid = ?";
c8092ea5 199 $DB->delete_records_select('comments', "contextid={$context->id} AND commentarea='glossary_entry' AND itemid IN ($entry_select)", array($id));
49bcd737 200 $DB->delete_records_select('glossary_alias', "entryid IN ($entry_select)", array($id));
201 $DB->delete_records_select('glossary_ratings', "entryid IN ($entry_select)", array($id));
202
203 $category_select = "SELECT id FROM {glossary_categories} WHERE glossaryid = ?";
204 $DB->delete_records_select('glossary_entries_categories', "categoryid IN ($category_select)", array($id));
205 $DB->delete_records('glossary_categories', array('glossaryid'=>$id));
206
fa686bc4 207 // delete all files
208 $fs->delete_area_files($context->id);
49bcd737 209
e6d45048 210 glossary_grade_item_delete($glossary);
07842023 211
49bcd737 212 return $DB->delete_records('glossary', array('id'=>$id));
07842023 213}
214
e121db76 215/**
216 * Return a small object with summary information about what a
217 * user has done with a given particular instance of this module
218 * Used for user activity reports.
219 * $return->time = the time they did it
220 * $return->info = a short text description
221 *
222 * @param object $course
223 * @param object $user
224 * @param object $mod
225 * @param object $glossary
226 * @return object|null
227 */
07842023 228function glossary_user_outline($course, $user, $mod, $glossary) {
1a96363a
NC
229 global $CFG;
230
231 require_once("$CFG->libdir/gradelib.php");
232 $grades = grade_get_grades($course->id, 'mod', 'glossary', $glossary->id, $user->id);
233 if (empty($grades->items[0]->grades)) {
234 $grade = false;
235 } else {
236 $grade = reset($grades->items[0]->grades);
237 }
07842023 238
1ac87c73 239 if ($entries = glossary_get_user_entries($glossary->id, $user->id)) {
e6d45048 240 $result = new object();
1ac87c73 241 $result->info = count($entries) . ' ' . get_string("entries", "glossary");
242
63dd5fb2 243 $lastentry = array_pop($entries);
244 $result->time = $lastentry->timemodified;
1a96363a
NC
245
246 if ($grade) {
247 $result->info .= ', ' . get_string('grade') . ': ' . $grade->str_long_grade;
248 }
249 return $result;
250 } else if ($grade) {
251 $result = new object();
252 $result->info = get_string('grade') . ': ' . $grade->str_long_grade;
253 $result->time = $grade->dategraded;
1ac87c73 254 return $result;
255 }
256 return NULL;
257}
258
e121db76 259/**
260 * @global object
261 * @param int $glossaryid
262 * @param int $userid
263 * @return array
264 */
1ac87c73 265function glossary_get_user_entries($glossaryid, $userid) {
266/// Get all the entries for a user in a glossary
ae8c3566 267 global $DB;
1ac87c73 268
ae8c3566 269 return $DB->get_records_sql("SELECT e.*, u.firstname, u.lastname, u.email, u.picture
270 FROM {glossary} g, {glossary_entries} e, {user} u
271 WHERE g.id = ?
a02c77dc 272 AND e.glossaryid = g.id
ae8c3566 273 AND e.userid = ?
1ac87c73 274 AND e.userid = u.id
ae8c3566 275 ORDER BY e.timemodified ASC", array($glossaryid, $userid));
07842023 276}
277
e121db76 278/**
279 * Print a detailed representation of what a user has done with
280 * a given particular instance of this module, for user activity reports.
281 *
282 * @global object
283 * @param object $course
284 * @param object $user
285 * @param object $mod
286 * @param object $glossary
287 */
07842023 288function glossary_user_complete($course, $user, $mod, $glossary) {
1a96363a
NC
289 global $CFG, $OUTPUT;
290 require_once("$CFG->libdir/gradelib.php");
291
292 $grades = grade_get_grades($course->id, 'mod', 'glossary', $glossary->id, $user->id);
293 if (!empty($grades->items[0]->grades)) {
294 $grade = reset($grades->items[0]->grades);
295 echo $OUTPUT->container(get_string('grade').': '.$grade->str_long_grade);
296 if ($grade->str_feedback) {
297 echo $OUTPUT->container(get_string('feedback').': '.$grade->str_feedback);
298 }
299 }
07842023 300
1ac87c73 301 if ($entries = glossary_get_user_entries($glossary->id, $user->id)) {
a359c29b 302 echo '<table width="95%" border="0"><tr><td>';
1ac87c73 303 foreach ($entries as $entry) {
304 $cm = get_coursemodule_from_instance("glossary", $glossary->id, $course->id);
305 glossary_print_entry($course, $cm, $glossary, $entry,"","",0);
306 echo '<p>';
307 }
a359c29b 308 echo '</td></tr></table>';
1ac87c73 309 }
07842023 310}
e121db76 311/**
312 * Given a course and a time, this module should find recent activity
313 * that has occurred in glossary activities and print it out.
314 * Return true if there was output, or false is there was none.
315 *
316 * @global object
317 * @global object
318 * @global object
319 * @param object $course
320 * @param object $viewfullnames
321 * @param int $timestart
322 * @return bool
323 */
dd97c328 324function glossary_print_recent_activity($course, $viewfullnames, $timestart) {
3097018f 325 global $CFG, $USER, $DB, $OUTPUT;
dd97c328 326
327 //TODO: use timestamp in approved field instead of changing timemodified when approving in 2.0
328
329 $modinfo = get_fast_modinfo($course);
330 $ids = array();
331 foreach ($modinfo->cms as $cm) {
332 if ($cm->modname != 'glossary') {
333 continue;
334 }
335 if (!$cm->uservisible) {
336 continue;
337 }
338 $ids[$cm->instance] = $cm->instance;
339 }
340
341 if (!$ids) {
342 return false;
343 }
344
345 $glist = implode(',', $ids); // there should not be hundreds of glossaries in one course, right?
07842023 346
ae8c3566 347 if (!$entries = $DB->get_records_sql("SELECT ge.id, ge.concept, ge.approved, ge.timemodified, ge.glossaryid,
348 ge.userid, u.firstname, u.lastname, u.email, u.picture
349 FROM {glossary_entries} ge
350 JOIN {user} u ON u.id = ge.userid
351 WHERE ge.glossaryid IN ($glist) AND ge.timemodified > ?
352 ORDER BY ge.timemodified ASC", array($timestart))) {
07842023 353 return false;
354 }
355
dd97c328 356 $editor = array();
a359c29b 357
dd97c328 358 foreach ($entries as $entryid=>$entry) {
359 if ($entry->approved) {
cf8eaebb 360 continue;
361 }
dd97c328 362
363 if (!isset($editor[$entry->glossaryid])) {
364 $editor[$entry->glossaryid] = has_capability('mod/glossary:approve', get_context_instance(CONTEXT_MODULE, $modinfo->instances['glossary'][$entry->glossaryid]->id));
07842023 365 }
07842023 366
dd97c328 367 if (!$editor[$entry->glossaryid]) {
368 unset($entries[$entryid]);
369 }
370 }
8f7dc7f1 371
dd97c328 372 if (!$entries) {
373 return false;
374 }
3097018f 375 echo $OUTPUT->heading(get_string('newentries', 'glossary').':');
dd97c328 376
377 $strftimerecent = get_string('strftimerecent');
378 foreach ($entries as $entry) {
379 $link = $CFG->wwwroot.'/mod/glossary/view.php?g='.$entry->glossaryid.'&amp;mode=entry&amp;hook='.$entry->id;
380 if ($entry->approved) {
381 $dimmed = '';
382 } else {
383 $dimmed = ' dimmed_text';
07842023 384 }
dd97c328 385 echo '<div class="head'.$dimmed.'">';
386 echo '<div class="date">'.userdate($entry->timemodified, $strftimerecent).'</div>';
387 echo '<div class="name">'.fullname($entry, $viewfullnames).'</div>';
388 echo '</div>';
389 echo '<div class="info"><a href="'.$link.'">'.format_text($entry->concept, true).'</a></div>';
07842023 390 }
391
dd97c328 392 return true;
07842023 393}
394
e121db76 395/**
396 * @global object
397 * @param object $log
398 */
1ac87c73 399function glossary_log_info($log) {
ae8c3566 400 global $DB;
1ac87c73 401
ae8c3566 402 return $DB->get_record_sql("SELECT e.*, u.firstname, u.lastname
403 FROM {glossary_entries} e, {user} u
404 WHERE e.id = ? AND u.id = ?", array($log->info, $log->userid));
1ac87c73 405}
406
e121db76 407/**
408 * Function to be run periodically according to the moodle cron
409 * This function searches for things that need to be done, such
410 * as sending out mail, toggling flags etc ...
411 * @return bool
412 */
07842023 413function glossary_cron () {
07842023 414 return true;
415}
416
d31bae70 417/**
418 * Return grade for given user or all users.
419 *
e121db76 420 * @global object
d31bae70 421 * @param int $glossaryid id of glossary
422 * @param int $userid optional user id, 0 means all users
423 * @return array array of grades, false if none
424 */
612607bd 425function glossary_get_user_grades($glossary, $userid=0) {
63e87951 426 /*global $DB;
63dd5fb2 427
ae8c3566 428 $params = array('userid'=>$userid, 'gid'=>$glossary->id);
429
430 $user = $userid ? "AND u.id = :userid" : "";
63dd5fb2 431
ac9b0805 432 $sql = "SELECT u.id, u.id AS userid, avg(gr.rating) AS rawgrade
ae8c3566 433 FROM {user} u, {glossary_entries} ge, {glossary_ratings} gr
e6d45048 434 WHERE u.id = ge.userid AND ge.id = gr.entryid
ae8c3566 435 AND gr.userid != u.id AND ge.glossaryid = :gid
e6d45048 436 $user
437 GROUP BY u.id";
438
63e87951
AD
439 return $DB->get_records_sql($sql, $params);*/
440 global $CFG;
441
442 require_once($CFG->dirroot.'/rating/lib.php');
443 $rm = new rating_manager();
444
445 $ratingoptions = new stdclass();
446
447 //need these to work backwards to get a context id. Is there a better way to get contextid from a module instance?
448 $ratingoptions->modulename = 'glossary';
449 $ratingoptions->moduleid = $glossary->id;
450
451 $ratingoptions->userid = $userid;
452 $ratingoptions->aggregationmethod = $glossary->assessed;
453 $ratingoptions->scaleid = $glossary->scale;
454 $ratingoptions->itemtable = 'glossary_entries';
455 $ratingoptions->itemtableusercolumn = 'userid';
456
457 return $rm->get_user_grades($ratingoptions);
e6d45048 458}
459
d31bae70 460/**
775f811a 461 * Update activity grades
d31bae70 462 *
e121db76 463 * @global object
464 * @global object
7f46236f 465 * @param object $glossary null means all glossaries (with extra cmidnumber property)
775f811a 466 * @param int $userid specific user only, 0 means all
d31bae70 467 */
612607bd 468function glossary_update_grades($glossary=null, $userid=0, $nullifnone=true) {
ae8c3566 469 global $CFG, $DB;
adcbb43a 470 require_once($CFG->libdir.'/gradelib.php');
e6d45048 471
775f811a 472 if (!$glossary->assessed) {
473 glossary_grade_item_update($glossary);
3e6303b7 474
775f811a 475 } else if ($grades = glossary_get_user_grades($glossary, $userid)) {
476 glossary_grade_item_update($glossary, $grades);
eafb9d9e 477
775f811a 478 } else if ($userid and $nullifnone) {
479 $grade = new object();
480 $grade->userid = $userid;
481 $grade->rawgrade = NULL;
482 glossary_grade_item_update($glossary, $grade);
a02c77dc 483
e6d45048 484 } else {
775f811a 485 glossary_grade_item_update($glossary);
486 }
487}
488
489/**
490 * Update all grades in gradebook.
e121db76 491 *
492 * @global object
775f811a 493 */
494function glossary_upgrade_grades() {
495 global $DB;
496
497 $sql = "SELECT COUNT('x')
498 FROM {glossary} g, {course_modules} cm, {modules} m
499 WHERE m.name='glossary' AND m.id=cm.module AND cm.instance=g.id";
500 $count = $DB->count_records_sql($sql);
501
502 $sql = "SELECT g.*, cm.idnumber AS cmidnumber, g.course AS courseid
503 FROM {glossary} g, {course_modules} cm, {modules} m
504 WHERE m.name='glossary' AND m.id=cm.module AND cm.instance=g.id";
505 if ($rs = $DB->get_recordset_sql($sql)) {
775f811a 506 $pbar = new progress_bar('glossaryupgradegrades', 500, true);
507 $i=0;
508 foreach ($rs as $glossary) {
509 $i++;
510 upgrade_set_timeout(60*5); // set up timeout, may also abort execution
511 glossary_update_grades($glossary, 0, false);
512 $pbar->update($i, $count, "Updating Glossary grades ($i/$count).");
e6d45048 513 }
775f811a 514 $rs->close();
e6d45048 515 }
516}
517
d31bae70 518/**
612607bd 519 * Create/update grade item for given glossary
d31bae70 520 *
e121db76 521 * @global object
dd232d01 522 * @param object $glossary object with extra cmidnumber
0b5a80a1 523 * @param mixed optional array/object of grade(s); 'reset' means reset grades in gradebook
612607bd 524 * @return int, 0 if ok, error code otherwise
d31bae70 525 */
0b5a80a1 526function glossary_grade_item_update($glossary, $grades=NULL) {
612607bd 527 global $CFG;
ae8c3566 528 require_once($CFG->libdir.'/gradelib.php');
529
7f46236f 530 $params = array('itemname'=>$glossary->name, 'idnumber'=>$glossary->cmidnumber);
e6d45048 531
5980d52f 532 if (!$glossary->assessed or $glossary->scale == 0) {
612607bd 533 $params['gradetype'] = GRADE_TYPE_NONE;
34601114 534
535 } else if ($glossary->scale > 0) {
e8586b5f 536 $params['gradetype'] = GRADE_TYPE_VALUE;
e6d45048 537 $params['grademax'] = $glossary->scale;
538 $params['grademin'] = 0;
539
540 } else if ($glossary->scale < 0) {
e8586b5f 541 $params['gradetype'] = GRADE_TYPE_SCALE;
e6d45048 542 $params['scaleid'] = -$glossary->scale;
e6d45048 543 }
544
0b5a80a1 545 if ($grades === 'reset') {
546 $params['reset'] = true;
547 $grades = NULL;
548 }
549
550 return grade_update('mod/glossary', $glossary->course, 'mod', 'glossary', $glossary->id, 0, $grades, $params);
e6d45048 551}
552
d31bae70 553/**
554 * Delete grade item for given glossary
1adbd2c3 555 *
e121db76 556 * @global object
dd232d01 557 * @param object $glossary object
d31bae70 558 */
e6d45048 559function glossary_grade_item_delete($glossary) {
612607bd 560 global $CFG;
561 require_once($CFG->libdir.'/gradelib.php');
562
b67ec72f 563 return grade_update('mod/glossary', $glossary->course, 'mod', 'glossary', $glossary->id, 0, NULL, array('deleted'=>1));
07842023 564}
565
e121db76 566/**
567 * Returns the users with data in one glossary
568 * (users with records in glossary_entries, students)
569 *
570 * @global object
571 * @param int $glossaryid
572 * @return array
573 */
05855091 574function glossary_get_participants($glossaryid) {
ae8c3566 575 global $DB;
05855091 576
577 //Get students
ae8c3566 578 $students = $DB->get_records_sql("SELECT DISTINCT u.id, u.id
579 FROM {user} u, {glossary_entries} g
585fb1f4 580 WHERE g.glossaryid = ? AND u.id = g.userid", array($glossaryid));
05855091 581
582 //Return students array (it contains an array of unique users)
ae8c3566 583 return $students;
05855091 584}
07842023 585
e121db76 586/**
587 * @global object
588 * @param int $gloassryid
589 * @param int $scaleid
590 * @return bool
591 */
0f1a97c2 592function glossary_scale_used ($glossaryid,$scaleid) {
593//This function returns if a scale is being used by one glossary
ae8c3566 594 global $DB;
a02c77dc 595
0f1a97c2 596 $return = false;
597
ae8c3566 598 $rec = $DB->get_record("glossary", array("id"=>$glossaryid, "scale"=>-$scaleid));
0f1a97c2 599
2127fedd 600 if (!empty($rec) && !empty($scaleid)) {
a02c77dc 601 $return = true;
602 }
603
0f1a97c2 604 return $return;
605}
606
85c9ebb9 607/**
608 * Checks if scale is being used by any instance of glossary
609 *
610 * This is used to find out if scale used anywhere
e121db76 611 *
612 * @global object
613 * @param int $scaleid
85c9ebb9 614 * @return boolean True if the scale is used by any glossary
615 */
616function glossary_scale_used_anywhere($scaleid) {
ae8c3566 617 global $DB;
618
619 if ($scaleid and $DB->record_exists('glossary', array('scale'=>-$scaleid))) {
85c9ebb9 620 return true;
621 } else {
622 return false;
623 }
624}
625
07842023 626//////////////////////////////////////////////////////////////////////////////////////
627/// Any other glossary functions go here. Each of them must have a name that
628/// starts with glossary_
629
e121db76 630/**
631 * This function return an array of valid glossary_formats records
632 * Everytime it's called, every existing format is checked, new formats
633 * are included if detected and old formats are deleted and any glossary
634 * using an invalid format is updated to the default (dictionary).
635 *
636 * @global object
637 * @global object
638 * @return array
639 */
a359c29b 640function glossary_get_available_formats() {
ae8c3566 641 global $CFG, $DB;
a359c29b 642
643 //Get available formats (plugin) and insert (if necessary) them into glossary_formats
77495793 644 $formats = get_list_of_plugins('mod/glossary/formats', 'TEMPLATE');
645 $pluginformats = array();
a359c29b 646 foreach ($formats as $format) {
647 //If the format file exists
648 if (file_exists($CFG->dirroot.'/mod/glossary/formats/'.$format.'/'.$format.'_format.php')) {
649 include_once($CFG->dirroot.'/mod/glossary/formats/'.$format.'/'.$format.'_format.php');
650 //If the function exists
651 if (function_exists('glossary_show_entry_'.$format)) {
77495793 652 //Acummulate it as a valid format
653 $pluginformats[] = $format;
a359c29b 654 //If the format doesn't exist in the table
ae8c3566 655 if (!$rec = $DB->get_record('glossary_formats', array('name'=>$format))) {
a359c29b 656 //Insert the record in glossary_formats
e6d45048 657 $gf = new object();
a359c29b 658 $gf->name = $format;
659 $gf->popupformatname = $format;
660 $gf->visible = 1;
ae8c3566 661 $DB->insert_record("glossary_formats",$gf);
a359c29b 662 }
663 }
664 }
665 }
666
667 //Delete non_existent formats from glossary_formats table
ae8c3566 668 $formats = $DB->get_records("glossary_formats");
a359c29b 669 foreach ($formats as $format) {
670 $todelete = false;
77495793 671 //If the format in DB isn't a valid previously detected format then delete the record
672 if (!in_array($format->name,$pluginformats)) {
a359c29b 673 $todelete = true;
a359c29b 674 }
675
676 if ($todelete) {
677 //Delete the format
ae8c3566 678 $DB->delete_records('glossary_formats', array('name'=>$format->name));
a359c29b 679 //Reasign existing glossaries to default (dictionary) format
ae8c3566 680 if ($glossaries = $DB->get_records('glossary', array('displayformat'=>$format->name))) {
a359c29b 681 foreach($glossaries as $glossary) {
ae8c3566 682 $DB->set_field('glossary','displayformat','dictionary', array('id'=>$glossary->id));
a359c29b 683 }
684 }
685 }
686 }
687
688 //Now everything is ready in glossary_formats table
ae8c3566 689 $formats = $DB->get_records("glossary_formats");
a359c29b 690
691 return $formats;
692}
693
e121db76 694/**
695 * @param bool $debug
696 * @param string $text
697 * @param int $br
698 */
1ac87c73 699function glossary_debug($debug,$text,$br=1) {
700 if ( $debug ) {
41905731 701 echo '<font color="red">' . $text . '</font>';
1ac87c73 702 if ( $br ) {
a9ef4a63 703 echo '<br />';
1ac87c73 704 }
705 }
07842023 706}
707
e121db76 708/**
709 *
710 * @global object
711 * @param int $glossaryid
712 * @param string $entrylist
713 * @param string $pivot
714 * @return array
715 */
ea14e783 716function glossary_get_entries($glossaryid, $entrylist, $pivot = "") {
ae8c3566 717 global $DB;
ea14e783 718 if ($pivot) {
719 $pivot .= ",";
720 }
07842023 721
ae8c3566 722 return $DB->get_records_sql("SELECT $pivot id,userid,concept,definition,format
723 FROM {glossary_entries}
724 WHERE glossaryid = ?
725 AND id IN ($entrylist)", array($glossaryid));
07842023 726}
359f2758 727
e121db76 728/**
729 * @global object
730 * @global object
731 * @param object $concept
732 * @param string $courseid
733 * @return array
734 */
359f2758 735function glossary_get_entries_search($concept, $courseid) {
ae8c3566 736 global $CFG, $DB;
359f2758 737
a02c77dc 738 //Check if the user is an admin
6c351232 739 $bypassadmin = 1; //This means NO (by default)
957f6fc9 740 if (has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_SYSTEM))) {
6c351232 741 $bypassadmin = 0; //This means YES
a02c77dc 742 }
6c351232 743
a02c77dc 744 //Check if the user is a teacher
6c351232 745 $bypassteacher = 1; //This means NO (by default)
81e956b9 746 if (has_capability('mod/glossary:manageentries', get_context_instance(CONTEXT_COURSE, $courseid))) {
6c351232 747 $bypassteacher = 0; //This means YES
a02c77dc 748 }
6c351232 749
95d56829 750 $conceptlower = moodle_strtolower(trim($concept));
359f2758 751
ae8c3566 752 $params = array('courseid1'=>$courseid, 'courseid2'=>$courseid, 'conceptlower'=>$conceptlower, 'concept'=>$concept);
c76e673a 753
ae8c3566 754 return $DB->get_records_sql("SELECT e.*, g.name as glossaryname, cm.id as cmid, cm.course as courseid
755 FROM {glossary_entries} e, {glossary} g,
756 {course_modules} cm, {modules} m
757 WHERE m.name = 'glossary' AND
758 cm.module = m.id AND
759 (cm.visible = 1 OR cm.visible = $bypassadmin OR
760 (cm.course = :courseid1 AND cm.visible = $bypassteacher)) AND
761 g.id = cm.instance AND
762 e.glossaryid = g.id AND
763 ( (e.casesensitive != 0 AND LOWER(concept) = :conceptlower) OR
764 (e.casesensitive = 0 and concept = :concept)) AND
765 (g.course = courseid2 OR g.globalglossary = 1) AND
766 e.usedynalink != 0 AND
767 g.usedynalink != 0", $params);
c76e673a 768}
07842023 769
e121db76 770/**
771 * @global object
772 * @global object
773 * @param object $course
774 * @param object $course
775 * @param object $glossary
776 * @param object $entry
777 * @param string $mode
778 * @param string $hook
779 * @param int $printicons
780 * @param int $displayformat
e121db76 781 * @param bool $printview
782 * @return mixed
783 */
63e87951 784function glossary_print_entry($course, $cm, $glossary, $entry, $mode='',$hook='',$printicons = 1, $displayformat = -1, $printview = false) {
b8340d19 785 global $USER, $CFG;
37d543b5 786 $return = false;
b1918034 787 if ( $displayformat < 0 ) {
788 $displayformat = $glossary->displayformat;
789 }
b620a995 790 if ($entry->approved or ($USER->id == $entry->userid) or ($mode == 'approval' and !$entry->approved) ) {
a359c29b 791 $formatfile = $CFG->dirroot.'/mod/glossary/formats/'.$displayformat.'/'.$displayformat.'_format.php';
ae06e00e 792 if ($printview) {
793 $functionname = 'glossary_print_entry_'.$displayformat;
794 } else {
795 $functionname = 'glossary_show_entry_'.$displayformat;
796 }
a359c29b 797
798 if (file_exists($formatfile)) {
799 include_once($formatfile);
800 if (function_exists($functionname)) {
63e87951 801 $return = $functionname($course, $cm, $glossary, $entry,$mode,$hook,$printicons);
ae06e00e 802 } else if ($printview) {
803 //If the glossary_print_entry_XXXX function doesn't exist, print default (old) print format
ccde17c3 804 $return = glossary_print_entry_default($entry, $glossary, $cm);
c76e673a 805 }
767a31c3 806 }
07842023 807 }
a359c29b 808 return $return;
07842023 809}
b8340d19 810
e121db76 811/**
812 * Default (old) print format used if custom function doesn't exist in format
813 *
814 * @param object $entry
815 * @param object $glossary
816 * @param object $cm
817 * @return void Output is echo'd
818 */
ccde17c3 819function glossary_print_entry_default ($entry, $glossary, $cm) {
097d705e 820 echo '<h3>'. strip_tags($entry->concept) . ': </h3>';
7d8a3cb0 821
822 $definition = $entry->definition;
823
7d8a3cb0 824 $definition = '<span class="nolink">' . strip_tags($definition) . '</span>';
825
ccde17c3 826 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
827 $definition = file_rewrite_pluginfile_urls($definition, 'pluginfile.php', $context->id, 'glossary_entry', $entry->id);
cbc2b5df 828
7d8a3cb0 829 $options = new object();
ae06e00e 830 $options->para = false;
cbc2b5df 831 $options->trusted = $entry->definitiontrust;
832 $definition = format_text($definition, $entry->definitionformat, $options);
ae06e00e 833 echo ($definition);
834 echo '<br /><br />';
835}
a359c29b 836
120a18f0 837/**
838 * Print glossary concept/term as a heading &lt;h3>
e121db76 839 * @param object $entry
120a18f0 840 */
81bdc9e9 841function glossary_print_entry_concept($entry) {
2d8e042e 842 global $OUTPUT;
7d8a3cb0 843 $options = new object();
d34b9c5f 844 $options->para = false;
2d8e042e 845 $text = format_text($OUTPUT->heading('<span class="nolink">' . $entry->concept . '</span>', 3, 'nolink'), FORMAT_MOODLE, $options);
ff8352de 846 if (!empty($entry->highlight)) {
847 $text = highlight($entry->highlight, $text);
848 }
849 echo $text;
81bdc9e9 850}
1d9ddaaf 851
e121db76 852/**
853 *
854 * @global object
855 * @global array
856 * @param object $entry
857 * @param object $glossary
858 * @param object $cm
859 */
ccde17c3 860function glossary_print_entry_definition($entry, $glossary, $cm) {
ae8c3566 861 global $DB;
701fff21 862
f287e69c 863 $definition = $entry->definition;
864
4e489ae9 865 global $GLOSSARY_EXCLUDECONCEPTS;
866
701fff21 867 //Calculate all the strings to be no-linked
868 //First, the concept
4e489ae9 869 $GLOSSARY_EXCLUDECONCEPTS=array($entry->concept);
701fff21 870 //Now the aliases
ae8c3566 871 if ( $aliases = $DB->get_records('glossary_alias', array('entryid'=>$entry->id))) {
701fff21 872 foreach ($aliases as $alias) {
4e489ae9 873 $GLOSSARY_EXCLUDECONCEPTS[]=trim($alias->alias);
701fff21 874 }
f287e69c 875 }
876
7d8a3cb0 877 $options = new object();
3eb2f7ec 878 $options->para = false;
cbc2b5df 879 $options->trusted = $entry->definitiontrust;
0f9a668f 880
ccde17c3 881 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
882 $definition = file_rewrite_pluginfile_urls($definition, 'pluginfile.php', $context->id, 'glossary_entry', $entry->id);
cbc2b5df 883
884 $text = format_text($definition, $entry->definitionformat, $options);
885
4e489ae9 886 // Stop excluding concepts from autolinking
887 unset($GLOSSARY_EXCLUDECONCEPTS);
cbc2b5df 888
ff8352de 889 if (!empty($entry->highlight)) {
890 $text = highlight($entry->highlight, $text);
891 }
359f2758 892 if (isset($entry->footer)) { // Unparsed footer info
893 $text .= $entry->footer;
894 }
ff8352de 895 echo $text;
1d9ddaaf 896}
897
e121db76 898/**
899 *
900 * @global object
901 * @param object $course
902 * @param object $cm
903 * @param object $glossary
904 * @param object $entry
905 * @param string $mode
906 * @param string $hook
907 * @param string $type
908 * @return string|void
909 */
b8340d19 910function glossary_print_entry_aliases($course, $cm, $glossary, $entry,$mode='',$hook='', $type = 'print') {
ae8c3566 911 global $DB;
912
81bdc9e9 913 $return = '';
ae8c3566 914 if ( $aliases = $DB->get_records('glossary_alias', array('entryid'=>$entry->id))) {
81bdc9e9 915 foreach ($aliases as $alias) {
33cc423e 916 if (trim($alias->alias)) {
81bdc9e9 917 if ($return == '') {
918 $return = '<select style="font-size:8pt">';
919 }
920 $return .= "<option>$alias->alias</option>";
921 }
922 }
923 if ($return != '') {
924 $return .= '</select>';
81bdc9e9 925 }
a02c77dc 926 }
1ac87c73 927 if ($type == 'print') {
81bdc9e9 928 echo $return;
929 } else {
930 return $return;
931 }
932}
933
e121db76 934/**
935 *
936 * @global object
937 * @global object
938 * @global object
939 * @param object $course
940 * @param object $cm
941 * @param object $glossary
942 * @param object $entry
943 * @param string $mode
944 * @param string $hook
945 * @param string $type
946 * @return string|void
947 */
b8340d19 948function glossary_print_entry_icons($course, $cm, $glossary, $entry, $mode='',$hook='', $type = 'print') {
4096752d 949 global $USER, $CFG, $DB, $OUTPUT;
a02c77dc 950
dabfd0ed 951 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
81bdc9e9 952
36ce6ea2 953 $output = false; //To decide if we must really return text in "return". Activate when needed only!
81bdc9e9 954 $importedentry = ($entry->sourceglossaryid == $glossary->id);
81bdc9e9 955 $ismainglossary = $glossary->mainglossary;
b8340d19 956
957
9362b9b6 958 $return = '<span class="commands">';
097d705e 959 // Differentiate links for each entry.
2d1e0971 960 $altsuffix = ': '.strip_tags(format_text($entry->concept));
961
81bdc9e9 962 if (!$entry->approved) {
36ce6ea2 963 $output = true;
b8340d19 964 $return .= get_string('entryishidden','glossary');
81bdc9e9 965 }
b8340d19 966
4f0c2d00 967 if (has_capability('mod/glossary:manageentries', $context) or (isloggedin() and has_capability('mod/glossary:write', $context) and $entry->userid == $USER->id)) {
81bdc9e9 968 // only teachers can export entries so check it out
0468976c 969 if (has_capability('mod/glossary:export', $context) and !$ismainglossary and !$importedentry) {
ae8c3566 970 $mainglossary = $DB->get_record('glossary', array('mainglossary'=>1,'course'=>$course->id));
81bdc9e9 971 if ( $mainglossary ) { // if there is a main glossary defined, allow to export the current entry
36ce6ea2 972 $output = true;
b5d0cafc 973 $return .= ' <a title="'.get_string('exporttomainglossary','glossary') . '" href="exportentry.php?id='.$entry->id.'&amp;prevmode='.$mode.'&amp;hook='.urlencode($hook).'"><img src="'.$OUTPUT->pix_url('export', 'glossary').'" class="iconsmall" alt="'.get_string('exporttomainglossary','glossary').$altsuffix.'" /></a>';
81bdc9e9 974 }
975 }
976
977 if ( $entry->sourceglossaryid ) {
b5d0cafc 978 $icon = $OUTPUT->pix_url('minus', 'glossary'); // graphical metaphor (minus) for deleting an imported entry
81bdc9e9 979 } else {
b5d0cafc 980 $icon = $OUTPUT->pix_url('t/delete');
81bdc9e9 981 }
982
ff1e2621 983 //Decide if an entry is editable:
984 // -It isn't a imported entry (so nobody can edit a imported (from secondary to main) entry)) and
985 // -The user is teacher or he is a student with time permissions (edit period or editalways defined).
516c7276 986 $ineditperiod = ((time() - $entry->timecreated < $CFG->maxeditingtime) || $glossary->editalways);
6cb34d44 987 if ( !$importedentry and (has_capability('mod/glossary:manageentries', $context) or ($entry->userid == $USER->id and ($ineditperiod and has_capability('mod/glossary:write', $context))))) {
36ce6ea2 988 $output = true;
49bcd737 989 $return .= " <a title=\"" . get_string("delete") . "\" href=\"deleteentry.php?id=$cm->id&amp;mode=delete&amp;entry=$entry->id&amp;prevmode=$mode&amp;hook=".urlencode($hook)."\"><img src=\"";
81bdc9e9 990 $return .= $icon;
097d705e 991 $return .= "\" class=\"iconsmall\" alt=\"" . get_string("delete") .$altsuffix."\" /></a> ";
a02c77dc 992
b5d0cafc 993 $return .= " <a title=\"" . get_string("edit") . "\" href=\"edit.php?cmid=$cm->id&amp;id=$entry->id&amp;mode=$mode&amp;hook=".urlencode($hook)."\"><img src=\"" . $OUTPUT->pix_url('t/edit') . "\" class=\"iconsmall\" alt=\"" . get_string("edit") .$altsuffix. "\" /></a>";
81bdc9e9 994 } elseif ( $importedentry ) {
41905731 995 $return .= " <font size=\"-1\">" . get_string("exportedentry","glossary") . "</font>";
81bdc9e9 996 }
997 }
86a3996d 998 if (has_capability('mod/glossary:exportentry', $context)
999 || ($entry->userid == $USER->id
1000 && has_capability('mod/glossary:exportownentry', $context))) {
24ba58ee 1001 require_once($CFG->libdir . '/portfoliolib.php');
0d06b6fd 1002 $button = new portfolio_add_button();
24ba58ee 1003 $button->set_callback_options('glossary_entry_portfolio_caller', array('id' => $cm->id, 'entryid' => $entry->id), '/mod/glossary/locallib.php');
59dd457e
PL
1004
1005 $filecontext = $context;
1006 if ($entry->sourceglossaryid == $cm->instance) {
1007 if ($maincm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) {
1008 $filecontext = get_context_instance(CONTEXT_MODULE, $maincm->id);
1009 }
1010 }
1011 $fs = get_file_storage();
1012 if ($files = $fs->get_area_files($filecontext->id, 'glossary_attachment', $entry->id, "timemodified", false)) {
1013 $button->set_formats(PORTFOLIO_FORMAT_RICHHTML);
24ba58ee
PL
1014 } else {
1015 $button->set_formats(PORTFOLIO_FORMAT_PLAINHTML);
59dd457e
PL
1016 }
1017
0d06b6fd 1018 $return .= $button->to_html(PORTFOLIO_ADD_ICON_LINK);
49a12552 1019 }
81bdc9e9 1020 $return .= "&nbsp;&nbsp;"; // just to make up a little the output in Mozilla ;)
36ce6ea2 1021
9362b9b6 1022 $return .= '</span>';
a02c77dc 1023
c8092ea5
DC
1024 if (has_capability('mod/glossary:comment', $context) and $glossary->allowcomments) {
1025 $output = true;
1026 if (!empty($CFG->usecomments)) {
36051c9e 1027 require_once($CFG->dirroot . '/comment/lib.php');
c8092ea5 1028 $cmt = new stdclass;
866354a9
DC
1029 $cmt->pluginname = 'glossary';
1030 $cmt->context = $context;
1031 $cmt->course = $course->id;
1032 $cmt->cm = $cm;
1033 $cmt->area = 'glossary_entry';
1034 $cmt->itemid = $entry->id;
c8092ea5
DC
1035 $cmt->showcount = true;
1036 $comment = new comment($cmt);
866354a9 1037 $return .= '<div>'.$comment->output(true).'</div>';
c8092ea5
DC
1038 }
1039 }
1040
36ce6ea2 1041 //If we haven't calculated any REAL thing, delete result ($return)
1042 if (!$output) {
1043 $return = '';
1044 }
1045 //Print or get
1ac87c73 1046 if ($type == 'print') {
81bdc9e9 1047 echo $return;
1048 } else {
1049 return $return;
a0d1e2bb 1050 }
1051}
1052
e121db76 1053/**
1054 * @param object $course
1055 * @param object $cm
1056 * @param object $glossary
1057 * @param object $entry
1058 * @param string $mode
1059 * @param object $hook
1060 * @param bool $printicons
e121db76 1061 * @param bool $aliases
63e87951 1062 * @return void
e121db76 1063 */
63e87951 1064function glossary_print_entry_lower_section($course, $cm, $glossary, $entry, $mode, $hook, $printicons, $aliases=true) {
26983d03 1065 if ($aliases) {
9362b9b6 1066 $aliases = glossary_print_entry_aliases($course, $cm, $glossary, $entry, $mode, $hook,'html');
26983d03 1067 }
9362b9b6 1068 $icons = '';
cbc2b5df 1069 if ($printicons) {
9362b9b6 1070 $icons = glossary_print_entry_icons($course, $cm, $glossary, $entry, $mode, $hook,'html');
1ac87c73 1071 }
63e87951 1072 if ($aliases || $icons || $entry->rating) {
9362b9b6 1073 echo '<table>';
a359c29b 1074 if ( $aliases ) {
9362b9b6 1075 echo '<tr valign="top"><td class="aliases">' .
1076 get_string('aliases','glossary').': '.$aliases . '</td></tr>';
a359c29b 1077 }
1078 if ($icons) {
9362b9b6 1079 echo '<tr valign="top"><td class="icons">'.$icons.'</td></tr>';
a359c29b 1080 }
63e87951 1081 if ($entry->rating) {
9362b9b6 1082 echo '<tr valign="top"><td class="ratings">';
63e87951 1083 glossary_print_entry_ratings($course, $entry);
a359c29b 1084 echo '</td></tr>';
1085 }
1086 echo '</table>';
81bdc9e9 1087 }
1088}
1089
e121db76 1090/**
1091 * @todo Document this function
1092 */
49bcd737 1093function glossary_print_entry_attachment($entry, $cm, $format=NULL, $align="right", $insidetable=true) {
1d9ddaaf 1094/// valid format values: html : Return the HTML link for the attachment as an icon
1095/// text : Return the HTML link for tha attachment as text
1096/// blank : Print the output to the screen
1097 if ($entry->attachment) {
77495793 1098 if ($insidetable) {
41905731 1099 echo "<table border=\"0\" width=\"100%\" align=\"$align\"><tr><td align=\"$align\" nowrap=\"nowrap\">\n";
77495793 1100 }
49bcd737 1101 echo glossary_print_attachments($entry, $cm, $format, $align);
77495793 1102 if ($insidetable) {
1103 echo "</td></tr></table>\n";
1104 }
1d9ddaaf 1105 }
1106}
1107
e121db76 1108/**
1109 * @global object
1110 * @param object $cm
1111 * @param object $entry
1112 * @param string $mode
1113 * @param string $align
1114 * @param bool $insidetable
1115 */
cbc2b5df 1116function glossary_print_entry_approval($cm, $entry, $mode, $align="right", $insidetable=true) {
f2a1963c 1117 global $CFG, $OUTPUT;
cff611fc 1118
cbc2b5df 1119 if ($mode == 'approval' and !$entry->approved) {
77495793 1120 if ($insidetable) {
a8466100 1121 echo '<table class="glossaryapproval" align="'.$align.'"><tr><td align="'.$align.'">';
77495793 1122 }
b5d0cafc 1123 echo '<a title="'.get_string('approve','glossary').'" href="approve.php?eid='.$entry->id.'&amp;mode='.$mode.'&amp;sesskey='.sesskey().'"><img align="'.$align.'" src="'.$OUTPUT->pix_url('i/approve') . '" style="border:0px; width:34px; height:34px" alt="'.get_string('approve','glossary').'" /></a>';
77495793 1124 if ($insidetable) {
a8466100 1125 echo '</td></tr></table>';
77495793 1126 }
1d9ddaaf 1127 }
1128}
07842023 1129
e121db76 1130/**
1131 * It returns all entries from all glossaries that matches the specified criteria
1132 * within a given $course. It performs an $extended search if necessary.
1133 * It restrict the search to only one $glossary if the $glossary parameter is set.
1134 *
1135 * @global object
1136 * @global object
1137 * @param object $course
1138 * @param array $searchterms
1139 * @param int $extended
1140 * @param object $glossary
1141 * @return array
1142 */
c80828fe 1143function glossary_search($course, $searchterms, $extended = 0, $glossary = NULL) {
ae8c3566 1144 global $CFG, $DB;
07842023 1145
c80828fe 1146 if ( !$glossary ) {
ae8c3566 1147 if ( $glossaries = $DB->get_records("glossary", array("course"=>$course->id)) ) {
c80828fe 1148 $glos = "";
1149 foreach ( $glossaries as $glossary ) {
1150 $glos .= "$glossary->id,";
1151 }
9cae3799 1152 $glos = substr($glos,0,-1);
c80828fe 1153 }
1154 } else {
1155 $glos = $glossary->id;
1156 }
a02c77dc 1157
81e956b9 1158 if (!has_capability('mod/glossary:manageentries', get_context_instance(CONTEXT_COURSE, $glossary->course))) {
ae8c3566 1159 $glossarymodule = $DB->get_record("modules", array("name"=>"glossary"));
6a22879b 1160 $onlyvisible = " AND g.id = cm.instance AND cm.visible = 1 AND cm.module = $glossarymodule->id";
ae8c3566 1161 $onlyvisibletable = ", {course_modules} cm";
07842023 1162 } else {
1163
1164 $onlyvisible = "";
1165 $onlyvisibletable = "";
1166 }
1167
ae8c3566 1168 if ($DB->sql_regex_supported()) {
1169 $REGEXP = $DB->sql_regex(true);
1170 $NOTREGEXP = $DB->sql_regex(false);
a02c77dc 1171 }
ae8c3566 1172 $LIKE = $DB->sql_ilike(); // case-insensitive
07842023 1173
ae8c3566 1174 $searchcond = array();
1175 $params = array();
1176 $i = 0;
1177
1178 $concat = $DB->sql_concat('e.concept', "' '", 'e.definition');
07842023 1179
1180
1181 foreach ($searchterms as $searchterm) {
ae8c3566 1182 $i++;
1183
1184 $NOT = ''; /// Initially we aren't going to perform NOT LIKE searches, only MSSQL and Oracle
1185 /// will use it to simulate the "-" operator with LIKE clause
07842023 1186
6f4bdb9c 1187 /// Under Oracle and MSSQL, trim the + and - operators and perform
ae8c3566 1188 /// simpler LIKE (or NOT LIKE) queries
1189 if (!$DB->sql_regex_supported()) {
1190 if (substr($searchterm, 0, 1) == '-') {
1191 $NOT = ' NOT ';
1192 }
6f4bdb9c 1193 $searchterm = trim($searchterm, '+-');
1194 }
1195
ae8c3566 1196 // TODO: +- may not work for non latin languages
1197
1198 if (substr($searchterm,0,1) == '+') {
1199 $searchterm = trim($searchterm, '+-');
1200 $searchterm = preg_quote($searchterm, '|');
1201 $searchcond[] = "$concat $REGEXP :ss$i";
1202 $params['ss'.$i] = "(^|[^a-zA-Z0-9])$searchterm([^a-zA-Z0-9]|$)";
1203
07842023 1204 } else if (substr($searchterm,0,1) == "-") {
ae8c3566 1205 $searchterm = trim($searchterm, '+-');
1206 $searchterm = preg_quote($searchterm, '|');
1207 $searchcond[] = "$concat $NOTREGEXP :ss$i";
1208 $params['ss'.$i] = "(^|[^a-zA-Z0-9])$searchterm([^a-zA-Z0-9]|$)";
1209
07842023 1210 } else {
ae8c3566 1211 $searchcond[] = "$concat $NOT $LIKE :ss$i";
1212 $params['ss'.$i] = "%$searchterm%";
07842023 1213 }
1214 }
1215
ae8c3566 1216 if (empty($searchcond)) {
1217 $totalcount = 0;
1218 return array();
1219 }
1220
1221 $searchcond = implode(" AND ", $searchcond);
07842023 1222
ae8c3566 1223 $sql = "SELECT e.*
1224 FROM {glossary_entries} e, {glossary} g $onlyvisibletable
1225 WHERE $searchcond
ad58adac 1226 AND (e.glossaryid = g.id or e.sourceglossaryid = g.id) $onlyvisible
ae8c3566 1227 AND g.id IN ($glos) AND e.approved <> 0";
07842023 1228
ae8c3566 1229 return $DB->get_records_sql($sql, $params);
07842023 1230}
1231
e121db76 1232/**
1233 * @global object
1234 * @param array $searchterms
1235 * @param object $glossary
1236 * @param bool $extended
1237 * @return array
1238 */
c80828fe 1239function glossary_search_entries($searchterms, $glossary, $extended) {
ae8c3566 1240 global $DB;
1241
1242 $course = $DB->get_record("course", array("id"=>$glossary->course));
c80828fe 1243 return glossary_search($course,$searchterms,$extended,$glossary);
1244}
1245
49bcd737 1246/**
1247 * if return=html, then return a html string.
1248 * if return=text, then return a text-only string.
1249 * otherwise, print HTML for non-images, and return image HTML
1250 * if attachment is an image, $align set its aligment.
e121db76 1251 *
1252 * @global object
1253 * @global object
49bcd737 1254 * @param object $entry
1255 * @param object $cm
1256 * @param string $type html, txt, empty
1257 * @param string $align left or right
e121db76 1258 * @return string image string or nothing depending on $type param
49bcd737 1259 */
1260function glossary_print_attachments($entry, $cm, $type=NULL, $align="left") {
d436d197 1261 global $CFG, $DB, $OUTPUT;
e179048e 1262
49bcd737 1263 if (!$context = get_context_instance(CONTEXT_MODULE, $cm->id)) {
1264 return '';
e179048e 1265 }
a02c77dc 1266
49bcd737 1267 if ($entry->sourceglossaryid == $cm->instance) {
1268 if (!$maincm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) {
1269 return '';
a02c77dc 1270 }
49bcd737 1271 $filecontext = get_context_instance(CONTEXT_MODULE, $maincm->id);
e179048e 1272
49bcd737 1273 } else {
1274 $filecontext = $context;
1275 }
e179048e 1276
49bcd737 1277 $strattachment = get_string('attachment', 'glossary');
e179048e 1278
49bcd737 1279 $fs = get_file_storage();
1280 $browser = get_file_browser();
e179048e 1281
49bcd737 1282 $imagereturn = '';
1283 $output = '';
e179048e 1284
49bcd737 1285 if ($files = $fs->get_area_files($filecontext->id, 'glossary_attachment', $entry->id, "timemodified", false)) {
1286 foreach ($files as $file) {
1287 $filename = $file->get_filename();
1288 $mimetype = $file->get_mimetype();
b5d0cafc 1289 $iconimage = '<img src="'.$OUTPUT->pix_url(file_mimetype_icon($mimetype)).'" class="icon" alt="'.$mimetype.'" />';
4eef1399 1290 $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$context->id.'/glossary_attachment/'.$entry->id.'/'.$filename);
e179048e 1291
49bcd737 1292 if ($type == 'html') {
1293 $output .= "<a href=\"$path\">$iconimage</a> ";
1294 $output .= "<a href=\"$path\">".s($filename)."</a>";
1295 $output .= "<br />";
18b8fbfa 1296
49bcd737 1297 } else if ($type == 'text') {
1298 $output .= "$strattachment ".s($filename).":\n$path\n";
e179048e 1299
49bcd737 1300 } else {
1301 if (in_array($mimetype, array('image/gif', 'image/jpeg', 'image/png'))) {
1302 // Image attachments don't get printed as links
1303 $imagereturn .= "<br /><img src=\"$path\" alt=\"\" />";
1304 } else {
1305 $output .= "<a href=\"$path\">$iconimage</a> ";
1306 $output .= filter_text("<a href=\"$path\">".s($filename)."</a>");
1307 $output .= '<br />';
18b8fbfa 1308 }
e179048e 1309 }
1310 }
1311 }
49bcd737 1312
1313 if ($type) {
1314 return $output;
1315 } else {
1316 echo $output;
1317 return $imagereturn;
1318 }
e179048e 1319}
1320
aa9bcfcd 1321/**
1322 * Lists all browsable file areas
e121db76 1323 *
1324 * @param object $course
1325 * @param object $cm
1326 * @param object $context
1327 * @return array
aa9bcfcd 1328 */
1329function glossary_get_file_areas($course, $cm, $context) {
1330 $areas = array();
aa9bcfcd 1331 return $areas;
1332}
1333
49bcd737 1334/**
1335 * Serves the glossary attachments. Implements needed access control ;-)
e121db76 1336 *
98edf7b6 1337 * @param object $course
1338 * @param object $cminfo
1339 * @param object $context
1340 * @param string $filearea
1341 * @param array $args
1342 * @param bool $forcedownload
86900a93 1343 * @return bool false if file not found, does not return if found - justsend the file
49bcd737 1344 */
98edf7b6 1345function glossary_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) {
49bcd737 1346 global $CFG, $DB;
a02c77dc 1347
49bcd737 1348 if (!$cminfo->uservisible) {
1349 return false;
1350 }
e179048e 1351
dc5c2bd9 1352 if ($filearea === 'glossary_attachment' or $filearea === 'glossary_entry') {
aa9bcfcd 1353 $entryid = (int)array_shift($args);
49bcd737 1354
0a8a7b6c 1355 if (!$cm = get_coursemodule_from_instance('glossary', $cminfo->instance, $course->id)) {
1356 return false;
1357 }
1358
1359 require_course_login($course, true, $cm);
1adbd2c3 1360
aa9bcfcd 1361 if (!$entry = $DB->get_record('glossary_entries', array('id'=>$entryid))) {
1362 return false;
e179048e 1363 }
49bcd737 1364
aa9bcfcd 1365 if (!$glossary = $DB->get_record('glossary', array('id'=>$cminfo->instance))) {
1366 return false;
1367 }
e179048e 1368
aa9bcfcd 1369 if ($glossary->defaultapproval and !$entry->approved and !has_capability('mod/glossary:approve', $context)) {
1370 return false;
1371 }
1372
1373 if ($entry->glossaryid == $cminfo->instance) {
1374 $filecontext = $context;
1375
1376 } else if ($entry->sourceglossaryid == $cminfo->instance) {
1377 if (!$maincm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) {
1378 print_error('invalidcoursemodule');
1379 }
1380 $filecontext = get_context_instance(CONTEXT_MODULE, $maincm->id);
1381
1382 } else {
1383 return false;
1384 }
1385
1386 $relativepath = '/'.implode('/', $args);
1387 $fullpath = $filecontext->id.$filearea.$entryid.$relativepath;
1388
1389 $fs = get_file_storage();
1390 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
1391 return false;
1392 }
1393
1394 // finally send the file
1395 send_stored_file($file, 0, 0, true); // download MUST be forced - security!
e179048e 1396 }
1397
aa9bcfcd 1398 return false;
e179048e 1399}
1400
e121db76 1401/**
1402 *
1403 */
ad58adac 1404function glossary_print_tabbed_table_end() {
9ca8cc08 1405 echo "</div></div>";
06d94a52 1406}
1407
e121db76 1408/**
1409 * @param object $cm
1410 * @param object $glossary
1411 * @param string $mode
1412 * @param string $hook
1413 * @param string $sortkey
1414 * @param string $sortorder
1415 */
1ac87c73 1416function glossary_print_approval_menu($cm, $glossary,$mode, $hook, $sortkey = '', $sortorder = '') {
a359c29b 1417 if ($glossary->showalphabet) {
7a3ec1af 1418 echo '<div class="glossaryexplain">' . get_string("explainalphabet","glossary") . '</div><br />';
677038ee 1419 }
1ac87c73 1420 glossary_print_special_links($cm, $glossary, $mode, $hook);
c76e673a 1421
c4a35419 1422 glossary_print_alphabet_links($cm, $glossary, $mode, $hook,$sortkey, $sortorder);
c76e673a 1423
1ac87c73 1424 glossary_print_all_links($cm, $glossary, $mode, $hook);
894ff63f 1425
db87439a 1426 glossary_print_sorting_links($cm, $mode, 'CREATION', 'asc');
c76e673a 1427}
e121db76 1428/**
1429 * @param object $cm
1430 * @param object $glossary
1431 * @param string $hook
1432 * @param string $sortkey
1433 * @param string $sortorder
1434 */
1ac87c73 1435function glossary_print_import_menu($cm, $glossary, $mode, $hook, $sortkey='', $sortorder = '') {
7a3ec1af 1436 echo '<div class="glossaryexplain">' . get_string("explainimport","glossary") . '</div>';
748b1932 1437}
1438
e121db76 1439/**
1440 * @param object $cm
1441 * @param object $glossary
1442 * @param string $hook
1443 * @param string $sortkey
1444 * @param string $sortorder
1445 */
1ac87c73 1446function glossary_print_export_menu($cm, $glossary, $mode, $hook, $sortkey='', $sortorder = '') {
7a3ec1af 1447 echo '<div class="glossaryexplain">' . get_string("explainexport","glossary") . '</div>';
748b1932 1448}
e121db76 1449/**
1450 * @param object $cm
1451 * @param object $glossary
1452 * @param string $hook
1453 * @param string $sortkey
1454 * @param string $sortorder
1455 */
1ac87c73 1456function glossary_print_alphabet_menu($cm, $glossary, $mode, $hook, $sortkey='', $sortorder = '') {
1457 if ( $mode != 'date' ) {
a359c29b 1458 if ($glossary->showalphabet) {
7a3ec1af 1459 echo '<div class="glossaryexplain">' . get_string("explainalphabet","glossary") . '</div><br />';
c197e607 1460 }
c76e673a 1461
1ac87c73 1462 glossary_print_special_links($cm, $glossary, $mode, $hook);
c76e673a 1463
c4a35419 1464 glossary_print_alphabet_links($cm, $glossary, $mode, $hook, $sortkey, $sortorder);
c197e607 1465
1ac87c73 1466 glossary_print_all_links($cm, $glossary, $mode, $hook);
c197e607 1467 } else {
1ac87c73 1468 glossary_print_sorting_links($cm, $mode, $sortkey,$sortorder);
1469 }
1470}
1471
e121db76 1472/**
1473 * @param object $cm
1474 * @param object $glossary
1475 * @param string $hook
1476 * @param string $sortkey
1477 * @param string $sortorder
1478 */
1ac87c73 1479function glossary_print_author_menu($cm, $glossary,$mode, $hook, $sortkey = '', $sortorder = '') {
a359c29b 1480 if ($glossary->showalphabet) {
7a3ec1af 1481 echo '<div class="glossaryexplain">' . get_string("explainalphabet","glossary") . '</div><br />';
c197e607 1482 }
1ac87c73 1483
c4a35419 1484 glossary_print_alphabet_links($cm, $glossary, $mode, $hook, $sortkey, $sortorder);
1ac87c73 1485 glossary_print_all_links($cm, $glossary, $mode, $hook);
7a3ec1af 1486 glossary_print_sorting_links($cm, $mode, $sortkey,$sortorder);
c76e673a 1487}
1488
e121db76 1489/**
1490 * @global object
1491 * @global object
1492 * @param object $cm
1493 * @param object $glossary
1494 * @param string $hook
1495 * @param object $category
1496 */
1ac87c73 1497function glossary_print_categories_menu($cm, $glossary, $hook, $category) {
c9472f43 1498 global $CFG, $DB, $OUTPUT;
a02c77dc 1499
dabfd0ed 1500 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
3a26f0ea 1501
41905731 1502 echo '<table border="0" width="100%">';
c197e607 1503 echo '<tr>';
c76e673a 1504
5bd76d7f 1505 echo '<td align="center" style="width:20%">';
0468976c 1506 if (has_capability('mod/glossary:managecategories', $context)) {
c76e673a 1507 $options['id'] = $cm->id;
1ac87c73 1508 $options['mode'] = 'cat';
1509 $options['hook'] = $hook;
5c2ed7e2 1510 echo $OUTPUT->single_button(new moodle_url("editcategories.php", $options), get_string("editcategories","glossary"), "get");
c76e673a 1511 }
c197e607 1512 echo '</td>';
c76e673a 1513
5bd76d7f 1514 echo '<td align="center" style="width:60%">';
c197e607 1515 echo '<b>';
c76e673a 1516
f8dab966 1517 $menu = array();
c76e673a 1518 $menu[GLOSSARY_SHOW_ALL_CATEGORIES] = get_string("allcategories","glossary");
1519 $menu[GLOSSARY_SHOW_NOT_CATEGORISED] = get_string("notcategorised","glossary");
677038ee 1520
ae8c3566 1521 $categories = $DB->get_records("glossary_categories", array("glossaryid"=>$glossary->id), "name ASC");
c197e607 1522 $selected = '';
c76e673a 1523 if ( $categories ) {
1524 foreach ($categories as $currentcategory) {
1525 $url = $currentcategory->id;
1526 if ( $category ) {
1527 if ($currentcategory->id == $category->id) {
1528 $selected = $url;
1529 }
1530 }
ae06e00e 1531 $menu[$url] = clean_text($currentcategory->name); //Only clean, not filters
c76e673a 1532 }
1533 }
1534 if ( !$selected ) {
1535 $selected = GLOSSARY_SHOW_NOT_CATEGORISED;
1536 }
1537
1538 if ( $category ) {
5bd76d7f 1539 echo format_text($category->name, FORMAT_PLAIN);
c76e673a 1540 } else {
1ac87c73 1541 if ( $hook == GLOSSARY_SHOW_NOT_CATEGORISED ) {
c76e673a 1542
1543 echo get_string("entrieswithoutcategory","glossary");
1544 $selected = GLOSSARY_SHOW_NOT_CATEGORISED;
1545
1ac87c73 1546 } elseif ( $hook == GLOSSARY_SHOW_ALL_CATEGORIES ) {
c76e673a 1547
1548 echo get_string("allcategories","glossary");
1549 $selected = GLOSSARY_SHOW_ALL_CATEGORIES;
1550
1551 }
1552 }
c197e607 1553 echo '</b></td>';
5bd76d7f 1554 echo '<td align="center" style="width:20%">';
1adbd2c3 1555
f8dab966
PS
1556 $select = new single_select(new moodle_url("/mod/glossary/view.php", array('id'=>$cm->id, 'mode'=>'cat')), 'hook', $menu, $selected, null, "catmenu");
1557 echo $OUTPUT->render($select);
677038ee 1558
c197e607 1559 echo '</td>';
1560 echo '</tr>';
c76e673a 1561
c197e607 1562 echo '</table>';
c76e673a 1563}
1564
e121db76 1565/**
1566 * @global object
1567 * @param object $cm
1568 * @param object $glossary
1569 * @param string $mode
1570 * @param string $hook
1571 */
1ac87c73 1572function glossary_print_all_links($cm, $glossary, $mode, $hook) {
a02c77dc 1573global $CFG;
a359c29b 1574 if ( $glossary->showall) {
c76e673a 1575 $strallentries = get_string("allentries", "glossary");
1ac87c73 1576 if ( $hook == 'ALL' ) {
c76e673a 1577 echo "<b>$strallentries</b>";
1578 } else {
1579 $strexplainall = strip_tags(get_string("explainall","glossary"));
839f2456 1580 echo "<a title=\"$strexplainall\" href=\"$CFG->wwwroot/mod/glossary/view.php?id=$cm->id&amp;mode=$mode&amp;hook=ALL\">$strallentries</a>";
c76e673a 1581 }
1582 }
1583}
1584
e121db76 1585/**
1586 * @global object
1587 * @param object $cm
1588 * @param object $glossary
1589 * @param string $mode
1590 * @param string $hook
1591 */
1ac87c73 1592function glossary_print_special_links($cm, $glossary, $mode, $hook) {
c76e673a 1593global $CFG;
a359c29b 1594 if ( $glossary->showspecial) {
c76e673a 1595 $strspecial = get_string("special", "glossary");
1ac87c73 1596 if ( $hook == 'SPECIAL' ) {
677038ee 1597 echo "<b>$strspecial</b> | ";
1598 } else {
1599 $strexplainspecial = strip_tags(get_string("explainspecial","glossary"));
839f2456 1600 echo "<a title=\"$strexplainspecial\" href=\"$CFG->wwwroot/mod/glossary/view.php?id=$cm->id&amp;mode=$mode&amp;hook=SPECIAL\">$strspecial</a> | ";
677038ee 1601 }
914cb260 1602 }
c76e673a 1603}
677038ee 1604
e121db76 1605/**
1606 * @global object
1607 * @param object $glossary
1608 * @param string $mode
1609 * @param string $hook
1610 * @param string $sortkey
1611 * @param string $sortorder
1612 */
c4a35419 1613function glossary_print_alphabet_links($cm, $glossary, $mode, $hook, $sortkey, $sortorder) {
c76e673a 1614global $CFG;
a359c29b 1615 if ( $glossary->showalphabet) {
c4274149 1616 $alphabet = explode(",", get_string("alphabet"));
677038ee 1617 $letters_by_line = 14;
1618 for ($i = 0; $i < count($alphabet); $i++) {
1ac87c73 1619 if ( $hook == $alphabet[$i] and $hook) {
677038ee 1620 echo "<b>$alphabet[$i]</b>";
1621 } else {
82015ed2 1622 echo "<a href=\"$CFG->wwwroot/mod/glossary/view.php?id=$cm->id&amp;mode=$mode&amp;hook=".urlencode($alphabet[$i])."&amp;sortkey=$sortkey&amp;sortorder=$sortorder\">$alphabet[$i]</a>";
677038ee 1623 }
1624 if ((int) ($i % $letters_by_line) != 0 or $i == 0) {
c197e607 1625 echo ' | ';
677038ee 1626 } else {
a9ef4a63 1627 echo '<br />';
677038ee 1628 }
767a31c3 1629 }
677038ee 1630 }
c76e673a 1631}
1632
e121db76 1633/**
1634 * @global object
1635 * @param object $cm
1636 * @param string $mode
1637 * @param string $sortkey
1638 * @param string $sortorder
1639 */
1ac87c73 1640function glossary_print_sorting_links($cm, $mode, $sortkey = '',$sortorder = '') {
e121db76 1641 global $CFG;
677038ee 1642
c4a35419 1643 $asc = get_string("ascending","glossary");
1644 $desc = get_string("descending","glossary");
1645 $bopen = '<b>';
1646 $bclose = '</b>';
a02c77dc 1647
c197e607 1648 $neworder = '';
468c120a 1649 $currentorder = '';
1650 $currentsort = '';
677038ee 1651 if ( $sortorder ) {
c197e607 1652 if ( $sortorder == 'asc' ) {
468c120a 1653 $currentorder = $asc;
839f2456 1654 $neworder = '&amp;sortorder=desc';
468c120a 1655 $newordertitle = get_string('changeto', 'glossary', $desc);
677038ee 1656 } else {
468c120a 1657 $currentorder = $desc;
839f2456 1658 $neworder = '&amp;sortorder=asc';
468c120a 1659 $newordertitle = get_string('changeto', 'glossary', $asc);
677038ee 1660 }
b5d0cafc 1661 $icon = " <img src=\"".$OUTPUT->pix_url($sortorder, 'glossary')."\" class=\"icon\" alt=\"$newordertitle\" />";
677038ee 1662 } else {
c4a35419 1663 if ( $sortkey != 'CREATION' and $sortkey != 'UPDATE' and
1664 $sortkey != 'FIRSTNAME' and $sortkey != 'LASTNAME' ) {
677038ee 1665 $icon = "";
c4a35419 1666 $newordertitle = $asc;
677038ee 1667 } else {
c4a35419 1668 $newordertitle = $desc;
839f2456 1669 $neworder = '&amp;sortorder=desc';
b5d0cafc 1670 $icon = ' <img src="'.$OUTPUT->pix_url('asc', 'glossary').'" class="icon" alt="'.$newordertitle.'" />';
677038ee 1671 }
1672 }
c4a35419 1673 $ficon = '';
1674 $fneworder = '';
1675 $fbtag = '';
1676 $fendbtag = '';
1677
1678 $sicon = '';
1679 $sneworder = '';
ae078733 1680
1681 $sbtag = '';
1682 $fbtag = '';
1683 $fendbtag = '';
1684 $sendbtag = '';
1685
c4a35419 1686 $sendbtag = '';
1687
1688 if ( $sortkey == 'CREATION' or $sortkey == 'FIRSTNAME' ) {
1689 $ficon = $icon;
1690 $fneworder = $neworder;
1691 $fordertitle = $newordertitle;
1692 $sordertitle = $asc;
1693 $fbtag = $bopen;
1694 $fendbtag = $bclose;
1695 } elseif ($sortkey == 'UPDATE' or $sortkey == 'LASTNAME') {
1696 $sicon = $icon;
1697 $sneworder = $neworder;
1698 $fordertitle = $asc;
1699 $sordertitle = $newordertitle;
1700 $sbtag = $bopen;
1701 $sendbtag = $bclose;
677038ee 1702 } else {
c4a35419 1703 $fordertitle = $asc;
1704 $sordertitle = $asc;
677038ee 1705 }
c4a35419 1706
1707 if ( $sortkey == 'CREATION' or $sortkey == 'UPDATE' ) {
1708 $forder = 'CREATION';
1709 $sorder = 'UPDATE';
1710 $fsort = get_string("sortbycreation", "glossary");
1711 $ssort = get_string("sortbylastupdate", "glossary");
1712
468c120a 1713 $currentsort = $fsort;
1714 if ($sortkey == 'UPDATE') {
1715 $currentsort = $ssort;
1716 }
c4a35419 1717 $sort = get_string("sortchronogically", "glossary");
1718 } elseif ( $sortkey == 'FIRSTNAME' or $sortkey == 'LASTNAME') {
1719 $forder = 'FIRSTNAME';
1720 $sorder = 'LASTNAME';
1721 $fsort = get_string("firstname");
1722 $ssort = get_string("lastname");
1723
468c120a 1724 $currentsort = $fsort;
1725 if ($sortkey == 'LASTNAME') {
1726 $currentsort = $ssort;
1727 }
c4a35419 1728 $sort = get_string("sortby", "glossary");
1729 }
468c120a 1730 $current = '<span class="accesshide">'.get_string('current', 'glossary', "$currentsort $currentorder").'</span>';
1731 echo "<br />$current $sort: $sbtag<a title=\"$ssort $sordertitle\" href=\"$CFG->wwwroot/mod/glossary/view.php?id=$cm->id&amp;sortkey=$sorder$sneworder&amp;mode=$mode\">$ssort$sicon</a>$sendbtag | ".
839f2456 1732 "$fbtag<a title=\"$fsort $fordertitle\" href=\"$CFG->wwwroot/mod/glossary/view.php?id=$cm->id&amp;sortkey=$forder$fneworder&amp;mode=$mode\">$fsort$ficon</a>$fendbtag<br />";
fb443f1a 1733}
ad58adac 1734
e121db76 1735/**
1736 *
1737 * @param object $entry0
1738 * @param object $entry1
1739 * @return int [-1 | 0 | 1]
1740 */
ad58adac 1741function glossary_sort_entries ( $entry0, $entry1 ) {
a02c77dc 1742
95d56829 1743 if ( moodle_strtolower(ltrim($entry0->concept)) < moodle_strtolower(ltrim($entry1->concept)) ) {
ad58adac 1744 return -1;
95d56829 1745 } elseif ( moodle_strtolower(ltrim($entry0->concept)) > moodle_strtolower(ltrim($entry1->concept)) ) {
ad58adac 1746 return 1;
1747 } else {
1748 return 0;
1749 }
1750}
1751
ed0201dd 1752
e121db76 1753/**
1754 * @global object
1755 * @global object
1756 * @global object
1757 * @param object $course
1758 * @param object $entry
e121db76 1759 * @return bool
1760 */
63e87951
AD
1761function glossary_print_entry_ratings($course, $entry) {
1762/* global $USER, $CFG, $DB;
a02c77dc 1763
ae8c3566 1764 $glossary = $DB->get_record('glossary', array('id'=>$entry->glossaryid));
1765 $glossarymod = $DB->get_record('modules', array('name'=>'glossary'));
1766 $cm = $DB->get_record_sql("SELECT *
1767 FROM {course_modules}
1768 WHERE course = ? AND module = ? and instance = ?", array($course->id, $glossarymod->id, $glossary->id));
a02c77dc 1769
bbbf2d40 1770 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
a359c29b 1771
4f0c2d00 1772 if (!empty($ratings) and isloggedin()) {
63dd5fb2 1773 $useratings = true;
63e87951 1774 if ($entry->rating->settings->assesstimestart and $entry->rating->settings->assesstimefinish) {
63dd5fb2 1775 if ($entry->timecreated < $ratings->assesstimestart or $entry->timecreated > $ratings->assesstimefinish) {
1776 $useratings = false;
1777 }
1778 }
1779 if ($useratings) {
0468976c 1780 if (has_capability('mod/glossary:viewrating', $context)) {
63dd5fb2 1781 glossary_print_ratings_mean($entry->id, $ratings->scale);
1782 if ($USER->id != $entry->userid) {
1783 glossary_print_rating_menu($entry->id, $USER->id, $ratings->scale);
1784 $ratingsmenuused = true;
1785 }
1786 } else if ($USER->id == $entry->userid) {
1787 glossary_print_ratings_mean($entry->id, $ratings->scale);
1788 } else if (!empty($ratings->allow) ) {
1789 glossary_print_rating_menu($entry->id, $USER->id, $ratings->scale);
1790 $ratingsmenuused = true;
1791 }
1792 }
1793 }
1794 return $ratingsmenuused;
63e87951
AD
1795 */
1796 global $OUTPUT;
1797 if( !empty($entry->rating) ){
1798 echo $OUTPUT->render($entry->rating);
1799 }
63dd5fb2 1800}
1801
e121db76 1802/**
1803 *
1804 * @global object
1805 * @global object
1806 * @global object
1807 * @param int $courseid
1808 * @param array $entries
1809 * @param int $displayformat
1810 */
b1918034 1811function glossary_print_dynaentry($courseid, $entries, $displayformat = -1) {
ae8c3566 1812 global $USER,$CFG, $DB;
cca6f7f1 1813
36a2b6bd 1814 echo '<div class="boxaligncenter">';
a8466100 1815 echo '<table class="glossarypopup" cellspacing="0"><tr>';
1816 echo '<td>';
1d9ddaaf 1817 if ( $entries ) {
1818 foreach ( $entries as $entry ) {
ae8c3566 1819 if (! $glossary = $DB->get_record('glossary', array('id'=>$entry->glossaryid))) {
5973a4c4 1820 print_error('invalidid', 'glossary');
cca6f7f1 1821 }
ae8c3566 1822 if (! $course = $DB->get_record('course', array('id'=>$glossary->course))) {
5973a4c4 1823 print_error('coursemisconf');
1d9ddaaf 1824 }
a8466100 1825 if (!$cm = get_coursemodule_from_instance('glossary', $entry->glossaryid, $glossary->course) ) {
5973a4c4 1826 print_error('invalidid', 'glossary');
1d9ddaaf 1827 }
1f63b7c6 1828
1829 //If displayformat is present, override glossary->displayformat
a359c29b 1830 if ($displayformat < 0) {
1f63b7c6 1831 $dp = $glossary->displayformat;
a359c29b 1832 } else {
1f63b7c6 1833 $dp = $displayformat;
1834 }
1835
a359c29b 1836 //Get popupformatname
ae8c3566 1837 $format = $DB->get_record('glossary_formats', array('name'=>$dp));
a359c29b 1838 $displayformat = $format->popupformatname;
1839
1840 //Check displayformat variable and set to default if necessary
1841 if (!$displayformat) {
1842 $displayformat = 'dictionary';
584dcac9 1843 }
1f63b7c6 1844
a359c29b 1845 $formatfile = $CFG->dirroot.'/mod/glossary/formats/'.$displayformat.'/'.$displayformat.'_format.php';
1846 $functionname = 'glossary_show_entry_'.$displayformat;
1847
1848 if (file_exists($formatfile)) {
1849 include_once($formatfile);
1850 if (function_exists($functionname)) {
1851 $functionname($course, $cm, $glossary, $entry,'','','','');
1852 }
1853 }
cca6f7f1 1854 }
cca6f7f1 1855 }
a8466100 1856 echo '</td>';
36a2b6bd 1857 echo '</tr></table></div>';
1d9ddaaf 1858}
4f4ca7b5 1859
e121db76 1860/**
1861 *
1862 * @global object
1863 * @param array $entries
1864 * @param array $aliases
1865 * @param array $categories
1866 * @return string
1867 */
6c0a9413 1868function glossary_generate_export_csv($entries, $aliases, $categories) {
1869 global $CFG;
1870 $csv = '';
1871 $delimiter = '';
1872 require_once($CFG->libdir . '/csvlib.class.php');
1873 $delimiter = csv_import_reader::get_delimiter('comma');
1874 $csventries = array(0 => array(get_string('concept', 'glossary'), get_string('definition', 'glossary')));
1875 $csvaliases = array(0 => array());
1876 $csvcategories = array(0 => array());
1877 $aliascount = 0;
1878 $categorycount = 0;
1879
1880 foreach ($entries as $entry) {
1881 $thisaliasesentry = array();
1882 $thiscategoriesentry = array();
cbc2b5df 1883 $thiscsventry = array($entry->concept, nl2br($entry->definition));
6c0a9413 1884
1885 if (array_key_exists($entry->id, $aliases) && is_array($aliases[$entry->id])) {
1886 $thiscount = count($aliases[$entry->id]);
1887 if ($thiscount > $aliascount) {
1888 $aliascount = $thiscount;
1889 }
1890 foreach ($aliases[$entry->id] as $alias) {
1891 $thisaliasesentry[] = trim($alias);
1892 }
1893 }
1894 if (array_key_exists($entry->id, $categories) && is_array($categories[$entry->id])) {
1895 $thiscount = count($categories[$entry->id]);
1896 if ($thiscount > $categorycount) {
1897 $categorycount = $thiscount;
1898 }
1899 foreach ($categories[$entry->id] as $catentry) {
1900 $thiscategoriesentry[] = trim($catentry);
1901 }
1902 }
1903 $csventries[$entry->id] = $thiscsventry;
1904 $csvaliases[$entry->id] = $thisaliasesentry;
1905 $csvcategories[$entry->id] = $thiscategoriesentry;
1906
1907 }
1908 $returnstr = '';
1909 foreach ($csventries as $id => $row) {
1910 $aliasstr = '';
1911 $categorystr = '';
1912 if ($id == 0) {
1913 $aliasstr = get_string('alias', 'glossary');
1914 $categorystr = get_string('category', 'glossary');
1915 }
1916 $row = array_merge($row, array_pad($csvaliases[$id], $aliascount, $aliasstr), array_pad($csvcategories[$id], $categorycount, $categorystr));
1917 $returnstr .= '"' . implode('"' . $delimiter . '"', $row) . '"' . "\n";
1918 }
1919 return $returnstr;
1920}
1921
e121db76 1922/**
1923 * @todo Check whether the third argument is valid
1924 * @global object
1925 * @global object
1926 * @param object $glossary
1927 * @param string $hook
1928 * @param int $hook
1929 * @return string
1930 */
1ac87c73 1931function glossary_generate_export_file($glossary, $hook = "", $hook = 0) {
ae8c3566 1932 global $CFG, $DB;
212039c0 1933
1934 $co = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
1935
1936 $co .= glossary_start_tag("GLOSSARY",0,true);
1937 $co .= glossary_start_tag("INFO",1,true);
1938 $co .= glossary_full_tag("NAME",2,false,$glossary->name);
1939 $co .= glossary_full_tag("INTRO",2,false,$glossary->intro);
212039c0 1940 $co .= glossary_full_tag("ALLOWDUPLICATEDENTRIES",2,false,$glossary->allowduplicatedentries);
1941 $co .= glossary_full_tag("DISPLAYFORMAT",2,false,$glossary->displayformat);
1942 $co .= glossary_full_tag("SHOWSPECIAL",2,false,$glossary->showspecial);
1943 $co .= glossary_full_tag("SHOWALPHABET",2,false,$glossary->showalphabet);
1944 $co .= glossary_full_tag("SHOWALL",2,false,$glossary->showall);
1945 $co .= glossary_full_tag("ALLOWCOMMENTS",2,false,$glossary->allowcomments);
1946 $co .= glossary_full_tag("USEDYNALINK",2,false,$glossary->usedynalink);
1947 $co .= glossary_full_tag("DEFAULTAPPROVAL",2,false,$glossary->defaultapproval);
1948 $co .= glossary_full_tag("GLOBALGLOSSARY",2,false,$glossary->globalglossary);
1949 $co .= glossary_full_tag("ENTBYPAGE",2,false,$glossary->entbypage);
4f4ca7b5 1950
ae8c3566 1951 if ( $entries = $DB->get_records("glossary_entries", array("glossaryid"=>$glossary->id))) {
212039c0 1952 $co .= glossary_start_tag("ENTRIES",2,true);
748b1932 1953 foreach ($entries as $entry) {
046a797c 1954 $permissiongranted = 1;
1ac87c73 1955 if ( $hook ) {
1956 switch ( $hook ) {
046a797c 1957 case "ALL":
1958 case "SPECIAL":
1959 break;
1960 default:
1ac87c73 1961 $permissiongranted = ($entry->concept[ strlen($hook)-1 ] == $hook);
046a797c 1962 break;
1963 }
1964 }
1ac87c73 1965 if ( $hook ) {
1966 switch ( $hook ) {
046a797c 1967 case GLOSSARY_SHOW_ALL_CATEGORIES:
1968 break;
1969 case GLOSSARY_SHOW_NOT_CATEGORISED:
ae8c3566 1970 $permissiongranted = !$DB->record_exists("glossary_entries_categories", array("entryid"=>$entry->id));
046a797c 1971 break;
1972 default:
ae8c3566 1973 $permissiongranted = $DB->record_exists("glossary_entries_categories", array("entryid"=>$entry->id, "categoryid"=>$hook));
046a797c 1974 break;
1975 }
1976 }
1977 if ( $entry->approved and $permissiongranted ) {
212039c0 1978 $co .= glossary_start_tag("ENTRY",3,true);
1979 $co .= glossary_full_tag("CONCEPT",4,false,trim($entry->concept));
cbc2b5df 1980 $co .= glossary_full_tag("DEFINITION",4,false,$entry->definition);
1981 $co .= glossary_full_tag("FORMAT",4,false,$entry->definitionformat);
212039c0 1982 $co .= glossary_full_tag("USEDYNALINK",4,false,$entry->usedynalink);
1983 $co .= glossary_full_tag("CASESENSITIVE",4,false,$entry->casesensitive);
1984 $co .= glossary_full_tag("FULLMATCH",4,false,$entry->fullmatch);
1985 $co .= glossary_full_tag("TEACHERENTRY",4,false,$entry->teacherentry);
748b1932 1986
ae8c3566 1987 if ( $aliases = $DB->get_records("glossary_alias", array("entryid"=>$entry->id))) {
212039c0 1988 $co .= glossary_start_tag("ALIASES",4,true);
7965be79 1989 foreach ($aliases as $alias) {
212039c0 1990 $co .= glossary_start_tag("ALIAS",5,true);
1991 $co .= glossary_full_tag("NAME",6,false,trim($alias->alias));
1992 $co .= glossary_end_tag("ALIAS",5,true);
7965be79 1993 }
212039c0 1994 $co .= glossary_end_tag("ALIASES",4,true);
7965be79 1995 }
ae8c3566 1996 if ( $catentries = $DB->get_records("glossary_entries_categories", array("entryid"=>$entry->id))) {
212039c0 1997 $co .= glossary_start_tag("CATEGORIES",4,true);
748b1932 1998 foreach ($catentries as $catentry) {
ae8c3566 1999 $category = $DB->get_record("glossary_categories", array("id"=>$catentry->categoryid));
748b1932 2000
212039c0 2001 $co .= glossary_start_tag("CATEGORY",5,true);
2002 $co .= glossary_full_tag("NAME",6,false,$category->name);
2003 $co .= glossary_full_tag("USEDYNALINK",6,false,$category->usedynalink);
2004 $co .= glossary_end_tag("CATEGORY",5,true);
748b1932 2005 }
212039c0 2006 $co .= glossary_end_tag("CATEGORIES",4,true);
748b1932 2007 }
4f4ca7b5 2008
212039c0 2009 $co .= glossary_end_tag("ENTRY",3,true);
4f4ca7b5 2010 }
2011 }
212039c0 2012 $co .= glossary_end_tag("ENTRIES",2,true);
748b1932 2013
4f4ca7b5 2014 }
748b1932 2015
2016
212039c0 2017 $co .= glossary_end_tag("INFO",1,true);
2018 $co .= glossary_end_tag("GLOSSARY",0,true);
4f4ca7b5 2019
212039c0 2020 return $co;
4f4ca7b5 2021}
212039c0 2022/// Functions designed by Eloy Lafuente
2023/// Functions to create, open and write header of the xml file
4f4ca7b5 2024
e121db76 2025/**
2026 * Read import file and convert to current charset
2027 *
2028 * @global object
2029 * @param string $file
2030 * @return string
2031 */
748b1932 2032function glossary_read_imported_file($file) {
9f79b50f 2033 require_once "../../lib/xmlize.php";
2034 global $CFG;
2035
748b1932 2036 $h = fopen($file,"r");
2037 $line = '';
2038 if ($h) {
2039 while ( !feof($h) ) {
b9656030 2040 $char = fread($h,1024);
748b1932 2041 $line .= $char;
2042 }
2043 fclose($h);
894ff63f 2044 }
792a76d8 2045 return xmlize($line, 0);
748b1932 2046}
4f4ca7b5 2047
e121db76 2048/**
2049 * Return the xml start tag
2050 *
2051 * @param string $tag
2052 * @param int $level
2053 * @param bool $endline
2054 * @return string
2055 */
4f4ca7b5 2056function glossary_start_tag($tag,$level=0,$endline=false) {
2057 if ($endline) {
2058 $endchar = "\n";
2059 } else {
2060 $endchar = "";
2061 }
2062 return str_repeat(" ",$level*2)."<".strtoupper($tag).">".$endchar;
2063}
a02c77dc 2064
e121db76 2065/**
2066 * Return the xml end tag
2067 * @param string $tag
2068 * @param int $level
2069 * @param bool $endline
2070 * @return string
2071 */
4f4ca7b5 2072function glossary_end_tag($tag,$level=0,$endline=true) {
2073 if ($endline) {
2074 $endchar = "\n";
2075 } else {
2076 $endchar = "";
2077 }
2078 return str_repeat(" ",$level*2)."</".strtoupper($tag).">".$endchar;
2079}
a02c77dc 2080
e121db76 2081/**
2082 * Return the start tag, the contents and the end tag
2083 *
2084 * @global object
2085 * @param string $tag
2086 * @param int $level
2087 * @param bool $endline
2088 * @param string $content
2089 * @return string
2090 */
212039c0 2091function glossary_full_tag($tag,$level=0,$endline=true,$content) {
9f79b50f 2092 global $CFG;
a02c77dc 2093
4f4ca7b5 2094 $st = glossary_start_tag($tag,$level,$endline);
212039c0 2095 $co = preg_replace("/\r\n|\r/", "\n", s($content));
4f4ca7b5 2096 $et = glossary_end_tag($tag,0,true);
2097 return $st.$co.$et;
2098}
2099
e121db76 2100/**
2101 * Returns a list of ratings for a particular entry - sorted.
2102 *
2103 * @global object
2104 * @param int $entryid
2105 * @param string $sort
2106 */
63dd5fb2 2107function glossary_get_ratings($entryid, $sort="u.firstname ASC") {
ae8c3566 2108 global $DB;
2109 return $DB->get_records_sql("SELECT u.*, r.rating, r.time
2110 FROM {glossary_ratings} r, {user} u
2111 WHERE r.entryid = ? AND r.userid = u.id
2112 ORDER BY $sort", array($entryid));
63dd5fb2 2113}
2114
e121db76 2115/**
2116 * How many unrated entries are in the given glossary for a given user?
2117 *
2118 * @global object
2119 * @param int $glossaryid
2120 * @param int $userid
2121 * @return int
2122 */
63dd5fb2 2123function glossary_count_unrated_entries($glossaryid, $userid) {
ae8c3566 2124 global $DB;
2125 if ($entries = $DB->get_record_sql("SELECT count('x') as num
2126 FROM {glossary_entries}
2127 WHERE glossaryid = ? AND userid <> ?", array($glossaryid, $userid))) {
2128
2129 if ($rated = $DB->get_record_sql("SELECT count(*) as num
2130 FROM {glossary_entries} e, {glossary_ratings} r
2131 WHERE e.glossaryid = ? AND e.id = r.entryid
2132 AND r.userid = ?", array($glossaryid, $userid))) {
63dd5fb2 2133 $difference = $entries->num - $rated->num;
2134 if ($difference > 0) {
2135 return $difference;
2136 } else {
2137 return 0; // Just in case there was a counting error
2138 }
2139 } else {
2140 return $entries->num;
2141 }
2142 } else {
2143 return 0;
2144 }
2145}
2146
e121db76 2147/**
2148 *
2149 * Returns the html code to represent any pagging bar. Paramenters are:
2150 *
2151 * The function dinamically show the first and last pages, and "scroll" over pages.
2152 * Fully compatible with Moodle's print_paging_bar() function. Perhaps some day this
2153 * could replace the general one. ;-)
2154 *
2155 * @param int $totalcount total number of records to be displayed
2156 * @param int $page page currently selected (0 based)
2157 * @param int $perpage number of records per page
2158 * @param string $baseurl url to link in each page, the string 'page=XX' will be added automatically.
1adbd2c3 2159 *
e121db76 2160 * @param int $maxpageallowed Optional maximum number of page allowed.
2161 * @param int $maxdisplay Optional maximum number of page links to show in the bar
2162 * @param string $separator Optional string to be used between pages in the bar
2163 * @param string $specialtext Optional string to be showed as an special link
2164 * @param string $specialvalue Optional value (page) to be used in the special link
2165 * @param bool $previousandnext Optional to decide if we want the previous and next links
2166 * @return string
2167 */
e2cf5316 2168function glossary_get_paging_bar($totalcount, $page, $perpage, $baseurl, $maxpageallowed=99999, $maxdisplay=20, $separator="&nbsp;", $specialtext="", $specialvalue=-1, $previousandnext = true) {
e2cf5316 2169
2170 $code = '';
2171
2172 $showspecial = false;
2173 $specialselected = false;
2174
2175 //Check if we have to show the special link
2176 if (!empty($specialtext)) {
2177 $showspecial = true;
2178 }
2179 //Check if we are with the special link selected
2180 if ($showspecial && $page == $specialvalue) {
2181 $specialselected = true;
a02c77dc 2182 }
e2cf5316 2183
2184 //If there are results (more than 1 page)
2185 if ($totalcount > $perpage) {
36a2b6bd 2186 $code .= "<div style=\"text-align:center\">";
e2cf5316 2187 $code .= "<p>".get_string("page").":";
2188
2189 $maxpage = (int)(($totalcount-1)/$perpage);
2190
2191 //Lower and upper limit of page
2192 if ($page < 0) {
2193 $page = 0;
2194 }
2195 if ($page > $maxpageallowed) {
2196 $page = $maxpageallowed;
2197 }
2198 if ($page > $maxpage) {
2199 $page = $maxpage;
2200 }
2201
2202 //Calculate the window of pages
2203 $pagefrom = $page - ((int)($maxdisplay / 2));
2204 if ($pagefrom < 0) {
2205 $pagefrom = 0;
2206 }
2207 $pageto = $pagefrom + $maxdisplay - 1;
2208 if ($pageto > $maxpageallowed) {
2209 $pageto = $maxpageallowed;
2210 }
2211 if ($pageto > $maxpage) {
2212 $pageto = $maxpage;
2213 }
2214
2215 //Some movements can be necessary if don't see enought pages
2216 if ($pageto - $pagefrom < $maxdisplay - 1) {
2217 if ($pageto - $maxdisplay + 1 > 0) {
2218 $pagefrom = $pageto - $maxdisplay + 1;
2219 }
2220 }
2221
2222 //Calculate first and last if necessary
2223 $firstpagecode = '';
2224 $lastpagecode = '';
2225 if ($pagefrom > 0) {
2226 $firstpagecode = "$separator<a href=\"{$baseurl}page=0\">1</a>";
2227 if ($pagefrom > 1) {
2228 $firstpagecode .= "$separator...";
2229 }
2230 }
2231 if ($pageto < $maxpage) {
2232 if ($pageto < $maxpage -1) {
2233 $lastpagecode = "$separator...";
2234 }
2235 $lastpagecode .= "$separator<a href=\"{$baseurl}page=$maxpage\">".($maxpage+1)."</a>";
2236 }
2237
2238 //Previous
2239 if ($page > 0 && $previousandnext) {
2240 $pagenum = $page - 1;
2241 $code .= "&nbsp;(<a href=\"{$baseurl}page=$pagenum\">".get_string("previous")."</a>)&nbsp;";
2242 }
2243
2244 //Add first
2245 $code .= $firstpagecode;
2246
2247 $pagenum = $pagefrom;
2248
2249 //List of maxdisplay pages
2250 while ($pagenum <= $pageto) {
2251 $pagetoshow = $pagenum +1;
2252 if ($pagenum == $page && !$specialselected) {
08ec7ec6 2253 $code .= "$separator<b>$pagetoshow</b>";
e2cf5316 2254 } else {
2255 $code .= "$separator<a href=\"{$baseurl}page=$pagenum\">$pagetoshow</a>";
2256 }
2257 $pagenum++;
2258 }
2259
2260 //Add last
2261 $code .= $lastpagecode;
2262
2263 //Next
2264 if ($page < $maxpage && $page < $maxpageallowed && $previousandnext) {
2265 $pagenum = $page + 1;
2266 $code .= "$separator(<a href=\"{$baseurl}page=$pagenum\">".get_string("next")."</a>)";
2267 }
2268
2269 //Add special
2270 if ($showspecial) {
2271 $code .= '<br />';
2272 if ($specialselected) {
08ec7ec6 2273 $code .= "<b>$specialtext</b>";
e2cf5316 2274 } else {
2275 $code .= "$separator<a href=\"{$baseurl}page=$specialvalue\">$specialtext</a>";
2276 }
2277 }
2278
2279 //End html
2280 $code .= "</p>";
36a2b6bd 2281 $code .= "</div>";
e2cf5316 2282 }
2283
2284 return $code;
2285}
e121db76 2286/**
2287 * @return array
2288 */
f3221af9 2289function glossary_get_view_actions() {
2290 return array('view','view all','view entry');
2291}
e121db76 2292/**
2293 * @return array
2294 */
f3221af9 2295function glossary_get_post_actions() {
c8092ea5 2296 return array('add category','add entry','approve entry','delete category','delete entry','edit category','update entry');
f3221af9 2297}
2298
0b5a80a1 2299
2300/**
2301 * Implementation of the function for printing the form elements that control
2302 * whether the course reset functionality affects the glossary.
e121db76 2303 * @param object $mform form passed by reference
0b5a80a1 2304 */
2305function glossary_reset_course_form_definition(&$mform) {
2306 $mform->addElement('header', 'glossaryheader', get_string('modulenameplural', 'glossary'));
2307 $mform->addElement('checkbox', 'reset_glossary_all', get_string('resetglossariesall','glossary'));
2308
2309 $mform->addElement('select', 'reset_glossary_types', get_string('resetglossaries', 'glossary'),
2310 array('main'=>get_string('mainglossary', 'glossary'), 'secondary'=>get_string('secondaryglossary', 'glossary')), array('multiple' => 'multiple'));
2311 $mform->setAdvanced('reset_glossary_types');
2312 $mform->disabledIf('reset_glossary_types', 'reset_glossary_all', 'checked');
2313
2314 $mform->addElement('checkbox', 'reset_glossary_notenrolled', get_string('deletenotenrolled', 'glossary'));
2315 $mform->disabledIf('reset_glossary_notenrolled', 'reset_glossary_all', 'checked');
2316
2317 $mform->addElement('checkbox', 'reset_glossary_ratings', get_string('deleteallratings'));
2318 $mform->disabledIf('reset_glossary_ratings', 'reset_glossary_all', 'checked');
2319
2320 $mform->addElement('checkbox', 'reset_glossary_comments', get_string('deleteallcomments'));
2321 $mform->disabledIf('reset_glossary_comments', 'reset_glossary_all', 'checked');
2322}
2323
2324/**
2325 * Course reset form defaults.
e121db76 2326 * @return array
0b5a80a1 2327 */
2328function glossary_reset_course_form_defaults($course) {
2329 return array('reset_glossary_all'=>0, 'reset_glossary_ratings'=>1, 'reset_glossary_comments'=>1, 'reset_glossary_notenrolled'=>0);
2330}
2331
2332/**
2333 * Removes all grades from gradebook
e121db76 2334 *
2335 * @global object
0b5a80a1 2336 * @param int $courseid
2337 * @param string optional type
2338 */
2339function glossary_reset_gradebook($courseid, $type='') {
ae8c3566 2340 global $DB;
0b5a80a1 2341
2342 switch ($type) {
2343 case 'main' : $type = "AND g.mainglossary=1"; break;
2344 case 'secondary' : $type = "AND g.mainglossary=0"; break;
2345 default : $type = ""; //all
2346 }
2347
2348 $sql = "SELECT g.*, cm.idnumber as cmidnumber, g.course as courseid
ae8c3566 2349 FROM {glossary} g, {course_modules} cm, {modules} m
2350 WHERE m.name='glossary' AND m.id=cm.module AND cm.instance=g.id AND g.course=? $type";
0b5a80a1 2351
ae8c3566 2352 if ($glossarys = $DB->get_records_sql($sql, array($courseid))) {
0b5a80a1 2353 foreach ($glossarys as $glossary) {
2354 glossary_grade_item_update($glossary, 'reset');
2355 }
2356 }
2357}
2358/**
2359 * Actual implementation of the rest coures functionality, delete all the
2360 * glossary responses for course $data->courseid.
e121db76 2361 *
2362 * @global object
0b5a80a1 2363 * @param $data the data submitted from the reset course.
2364 * @return array status array
2365 */
2366function glossary_reset_userdata($data) {
ae8c3566 2367 global $CFG, $DB;
0b5a80a1 2368
2369 $componentstr = get_string('modulenameplural', 'glossary');
2370 $status = array();
2371
2372 $allentriessql = "SELECT e.id
ae8c3566 2373 FROM {glossary_entries} e
2374 JOIN {glossary} g ON e.glossaryid = g.id
2375 WHERE g.course = ?";
0b5a80a1 2376
2377 $allglossariessql = "SELECT g.id
ae8c3566 2378 FROM {glossary} g
2379 WHERE g.course = ?";
2380
2381 $params = array($data->courseid);
0b5a80a1 2382
49bcd737 2383 $fs = get_file_storage();
2384
0b5a80a1 2385 // delete entries if requested
2386 if (!empty($data->reset_glossary_all)
2387 or (!empty($data->reset_glossary_types) and in_array('main', $data->reset_glossary_types) and in_array('secondary', $data->reset_glossary_types))) {
2388
ae8c3566 2389 $DB->delete_records_select('glossary_ratings', "entryid IN ($allentriessql)", $params);
03221650 2390 // TODO: delete comments
c8092ea5 2391 //$DB->delete_records_select('comments', "entryid IN ($allentriessql)", array());
ae8c3566 2392 $DB->delete_records_select('glossary_entries', "glossaryid IN ($allglossariessql)", $params);
0b5a80a1 2393
49bcd737 2394 // now get rid of all attachments
ae8c3566 2395 if ($glossaries = $DB->get_records_sql($allglossariessql, $params)) {
0b5a80a1 2396 foreach ($glossaries as $glossaryid=>$unused) {
49bcd737 2397 if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) {
2398 continue;
2399 }
2400 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
2401 $fs->delete_area_files($context->id, 'glossary_attachment');
0b5a80a1 2402 }
2403 }
2404
2405 // remove all grades from gradebook
2406 if (empty($data->reset_gradebook_grades)) {
2407 glossary_reset_gradebook($data->courseid);
2408 }
2409
2410 $status[] = array('component'=>$componentstr, 'item'=>get_string('resetglossariesall', 'glossary'), 'error'=>false);
2411
2412 } else if (!empty($data->reset_glossary_types)) {
2413 $mainentriessql = "$allentries AND g.mainglossary=1";
2414 $secondaryentriessql = "$allentries AND g.mainglossary=0";
2415
2416 $mainglossariessql = "$allglossariessql AND g.mainglossary=1";
2417 $secondaryglossariessql = "$allglossariessql AND g.mainglossary=0";
2418
2419 if (in_array('main', $data->reset_glossary_types)) {
ae8c3566 2420 $DB->delete_records_select('glossary_ratings', "entryid IN ($mainentriessql)", $params);
2421 $DB->delete_records_select('glossary_comments', "entryid IN ($mainentriessql)", $params);
2422 $DB->delete_records_select('glossary_entries', "glossaryid IN ($mainglossariessql)", $params);
0b5a80a1 2423
ae8c3566 2424 if ($glossaries = $DB->get_records_sql($mainglossariessql, $params)) {
0b5a80a1 2425 foreach ($glossaries as $glossaryid=>$unused) {
49bcd737 2426 if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) {
2427 continue;
2428 }
2429 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
2430 $fs->delete_area_files($context->id, 'glossary_attachment');
0b5a80a1 2431 }
2432 }
2433
2434 // remove all grades from gradebook
2435 if (empty($data->reset_gradebook_grades)) {
2436 glossary_reset_gradebook($data->courseid, 'main');
2437 }
2438
2439 $status[] = array('component'=>$componentstr, 'item'=>get_string('resetglossaries', 'glossary'), 'error'=>false);
2440
2441 } else if (in_array('secondary', $data->reset_glossary_types)) {
ae8c3566 2442 $DB->delete_records_select('glossary_ratings', "entryid IN ($secondaryentriessql)", $params);
2443 $DB->delete_records_select('glossary_comments', "entryid IN ($secondaryentriessql)", $params);
2444 $DB->delete_records_select('glossary_entries', "glossaryid IN ($secondaryglossariessql)", $params);
0b5a80a1 2445 // remove exported source flag from entries in main glossary
ae8c3566 2446 $DB->execute("UPDATE {glossary_entries
2447 SET sourceglossaryid=0
2448 WHERE glossaryid IN ($mainglossariessql)", $params);
0b5a80a1 2449
ae8c3566 2450 if ($glossaries = $DB->get_records_sql($secondaryglossariessql, $params)) {
0b5a80a1 2451 foreach ($glossaries as $glossaryid=>$unused) {
49bcd737 2452 if (!$cm = get_coursemodule_from_instance('glossary', $glossaryid)) {
2453 continue;
2454 }
2455 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
2456 $fs->delete_area_files($context->id, 'glossary_attachment');
0b5a80a1 2457 }
2458 }
2459
2460 // remove all grades from gradebook
2461 if (empty($data->reset_gradebook_grades)) {
2462 glossary_reset_gradebook($data->courseid, 'secondary');
2463 }
2464
2465 $status[] = array('component'=>$componentstr, 'item'=>get_string('resetglossaries', 'glossary').': '.get_string('secondaryglossary', 'glossary'), 'error'=>false);
2466 }
2467 }
2468
2469 // remove entries by users not enrolled into course
2470 if (!empty($data->reset_glossary_notenrolled)) {
2471 $entriessql = "SELECT e.id, e.userid, e.glossaryid, u.id AS userexists, u.deleted AS userdeleted
ae8c3566 2472 FROM {glossary_entries} e
2473 JOIN {glossary} g ON e.glossaryid = g.id
2474 LEFT JOIN {user} u ON e.userid = u.id
2475 WHERE g.course = ? AND e.userid > 0";
0b5a80a1 2476
2477 $course_context = get_context_instance(CONTEXT_COURSE, $data->courseid);
2478 $notenrolled = array();
ae8c3566 2479 if ($rs = $DB->get_recordset_sql($entriessql, $params)) {
2480 foreach ($rs as $entry) {
0b5a80a1 2481 if (array_key_exists($entry->userid, $notenrolled) or !$entry->userexists or $entry->userdeleted
4f0c2d00 2482 or !is_enrolled($course_context , $entry->userid)) {
ae8c3566 2483 $DB->delete_records('glossary_ratings', array('entryid'=>$entry->id));
2484 $DB->delete_records('glossary_comments', array('entryid'=>$entry->id));
2485 $DB->delete_records('glossary_entries', array('id'=>$entry->id));
49bcd737 2486
2487 if ($cm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) {
2488 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
2489 $fs->delete_area_files($context->id, 'glossary_attachment', $entry->id);
2490 }
0b5a80a1 2491 }
2492 }
ae8c3566 2493 $rs->close();
0b5a80a1 2494 $status[] = array('component'=>$componentstr, 'item'=>get_string('deletenotenrolled', 'glossary'), 'error'=>false);
2495 }
2496 }
2497
2498 // remove all ratings
2499 if (!empty($data->reset_glossary_ratings)) {
ae8c3566 2500 $DB->delete_records_select('glossary_ratings', "entryid IN ($allentriessql)", $params);
0b5a80a1 2501 // remove all grades from gradebook
2502 if (empty($data->reset_gradebook_grades)) {
2503 glossary_reset_gradebook($data->courseid);
2504 }
2505 $status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallratings'), 'error'=>false);
2506 }
2507
c8092ea5 2508 // TODO: remove all comments
0b5a80a1 2509 if (!empty($data->reset_glossary_comments)) {
ae8c3566 2510 $DB->delete_records_select('glossary_comments', "entryid IN ($allentriessql)", $params);
0b5a80a1 2511 $status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallcomments'), 'error'=>false);
2512 }
2513
2514 /// updating dates - shift may be negative too
2515 if ($data->timeshift) {
2516 shift_course_mod_dates('glossary', array('assesstimestart', 'assesstimefinish'), $data->timeshift, $data->courseid);
2517 $status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false);
2518 }
2519
2520 return $status;
2521}
2522
f432bebf 2523/**
2524 * Returns all other caps used in module
e121db76 2525 * @return array
f432bebf 2526 */
2527function glossary_get_extra_capabilities() {
2528 return array('moodle/site:accessallgroups', 'moodle/site:viewfullnames', 'moodle/site:trustcontent');
2529}
2530
18a2a0cb 2531/**
2532 * @param string $feature FEATURE_xx constant for requested feature
2533 * @return mixed True if module supports feature, null if doesn't know
2534 */
2535function glossary_supports($feature) {
2536 switch($feature) {
42f103be 2537 case FEATURE_GROUPS: return false;
2538 case FEATURE_GROUPINGS: return false;
2539 case FEATURE_GROUPMEMBERSONLY: return true;
dc5c2bd9 2540 case FEATURE_MOD_INTRO: return true;
18a2a0cb 2541 case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
42f103be 2542 case FEATURE_GRADE_HAS_GRADE: return true;
2543 case FEATURE_GRADE_OUTCOMES: return true;
63e87951 2544 case FEATURE_RATE: return true;
42f103be 2545
18a2a0cb 2546 default: return null;
2547 }
2548}
0961861e 2549
2550function glossary_extend_navigation($navigation, $course, $module, $cm) {
2551 global $CFG;
a6855934
PS
2552 $navigation->add(get_string('standardview', 'glossary'), new moodle_url('/mod/glossary/view.php', array('id'=>$cm->id, 'mode'=>'letter')));
2553 $navigation->add(get_string('categoryview', 'glossary'), new moodle_url('/mod/glossary/view.php', array('id'=>$cm->id, 'mode'=>'cat')));
2554 $navigation->add(get_string('dateview', 'glossary'), new moodle_url('/mod/glossary/view.php', array('id'=>$cm->id, 'mode'=>'date')));
2555 $navigation->add(get_string('authorview', 'glossary'), new moodle_url('/mod/glossary/view.php', array('id'=>$cm->id, 'mode'=>'author')));
0961861e 2556}
2557
0b29477b
SH
2558/**
2559 * Adds module specific settings to the settings block
2560 *
2561 * @param settings_navigation $settings The settings navigation object
2562 * @param navigation_node $glossarynode The node to add module settings to
2563 */
2564function glossary_extend_settings_navigation(settings_navigation $settings, navigation_node $glossarynode) {
56115eea 2565 global $PAGE, $DB, $CFG;
0961861e 2566
2567 $mode = optional_param('mode', '', PARAM_ALPHA);
2568 $hook = optional_param('hook', 'ALL', PARAM_CLEAN);
2569
0961861e 2570 if (has_capability('mod/glossary:import', $PAGE->cm->context)) {
0b29477b 2571 $glossarynode->add(get_string('importentries', 'glossary'), new moodle_url('/mod/glossary/import.php', array('id'=>$PAGE->cm->id)));
0961861e 2572 }
2573
2574 if (has_capability('mod/glossary:export', $PAGE->cm->context)) {
0b29477b 2575 $glossarynode->add(get_string('exportentries', 'glossary'), new moodle_url('/mod/glossary/export.php', array('id'=>$PAGE->cm->id, 'mode'=>$mode, 'hook'=>$hook)));
0961861e 2576 }
2577
56115eea 2578 if (has_capability('mod/glossary:approve', $PAGE->cm->context) && ($hiddenentries = $DB->count_records('glossary_entries', array('glossaryid'=>$PAGE->cm->instance, 'approved'=>0)))) {
0b29477b 2579 $glossarynode->add(get_string('waitingapproval', 'glossary'), new moodle_url('/mod/glossary/view.php', array('id'=>$PAGE->cm->id, 'mode'=>'approval')));
0961861e 2580 }
2581
2582 if (has_capability('mod/glossary:write', $PAGE->cm->context)) {
0b29477b 2583 $glossarynode->add(get_string('addentry', 'glossary'), new moodle_url('/mod/glossary/edit.php', array('cmid'=>$PAGE->cm->id)));
0961861e 2584 }
3406acde 2585}