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