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