Robustness on an optional variable
[moodle.git] / mod / glossary / lib.php
CommitLineData
07842023 1<?PHP // $Id$
2
3/// Library of functions and constants for module glossary
4/// (replace glossary with the name of your module and delete this line)
5
e179048e 6require_once("$CFG->dirroot/files/mimetypes.php");
07842023 7
8function glossary_add_instance($glossary) {
9/// Given an object containing all the necessary data,
10/// (defined by the form in mod.html) this function
11/// will create a new instance and return the id number
12/// of the new instance.
13
14 $glossary->timecreated = time();
15 $glossary->timemodified = $glossary->timecreated;
16
17 # May have to add extra stuff in here #
18
19 return insert_record("glossary", $glossary);
20}
21
22
23function glossary_update_instance($glossary) {
24/// Given an object containing all the necessary data,
25/// (defined by the form in mod.html) this function
26/// will update an existing instance with new data.
27
28 $glossary->timemodified = time();
29 $glossary->id = $glossary->instance;
30
31 # May have to add extra stuff in here #
32
33 return update_record("glossary", $glossary);
34}
35
36
37function glossary_delete_instance($id) {
38/// Given an ID of an instance of this module,
39/// this function will permanently delete the instance
40/// and any data that depends on it.
41
42 if (! $glossary = get_record("glossary", "id", "$id")) {
43 return false;
44 }
45
46 $result = true;
47
48 # Delete any dependent records here #
49
50 if (! delete_records("glossary", "id", "$glossary->id")) {
51 $result = false;
52 }
53 delete_records("glossary_entries", "glossaryid", "$glossary->id");
54
55 return $result;
56}
57
58function glossary_user_outline($course, $user, $mod, $glossary) {
59/// Return a small object with summary information about what a
60/// user has done with a given particular instance of this module
61/// Used for user activity reports.
62/// $return->time = the time they did it
63/// $return->info = a short text description
64
65 return $return;
66}
67
68function glossary_user_complete($course, $user, $mod, $glossary) {
69/// Print a detailed representation of what a user has done with
70/// a given particular instance of this module, for user activity reports.
71
72 return true;
73}
74
75function glossary_print_recent_activity($course, $isteacher, $timestart) {
76/// Given a course and a time, this module should find recent activity
77/// that has occurred in glossary activities and print it out.
78/// Return true if there was output, or false is there was none.
79
80 global $CFG, $THEME;
81
82 if (!$logs = get_records_select("log", "time > '$timestart' AND ".
83 "course = '$course->id' AND ".
84 "module = 'glossary' AND ".
85 "action = 'add %' ", "time ASC")) {
86 return false;
87 }
88
07842023 89 foreach ($logs as $log) {
90 //Create a temp valid module structure (course,id)
91 $tempmod->course = $log->course;
92 $tempmod->id = $log->info;
93 //Obtain the visible property from the instance
94 $modvisible = instance_is_visible($log->module,$tempmod);
07842023 95
96 //Only if the mod is visible
97 if ($modvisible) {
98 $entries[$log->info] = glossary_log_info($log);
99 $entries[$log->info]->time = $log->time;
100 $entries[$log->info]->url = $log->url;
101 }
07842023 102 }
103
07842023 104 $content = false;
105 if ($entries) {
106 $strftimerecent = get_string("strftimerecent");
107 $content = true;
108 print_headline(get_string("newentries", "glossary").":");
109 foreach ($entries as $entry) {
110 $date = userdate($entry->timemodified, $strftimerecent);
111 echo "<p><font size=1>$date - $entry->firstname $entry->lastname<br>";
112 echo "\"<a href=\"$CFG->wwwroot/mod/glossary/$entry->url\">";
113 echo "$entry->concept";
114 echo "</a>\"</font></p>";
115 }
116 }
117
118 return $content;
119}
120
121function glossary_cron () {
122/// Function to be run periodically according to the moodle cron
123/// This function searches for things that need to be done, such
124/// as sending out mail, toggling flags etc ...
125
126 global $CFG;
127
128 return true;
129}
130
131function glossary_grades($glossaryid) {
132/// Must return an array of grades for a given instance of this module,
133/// indexed by user. It also returns a maximum allowed grade.
134
135 $return->grades = NULL;
136 $return->maxgrade = NULL;
137
138 return $return;
139}
140
141
142//////////////////////////////////////////////////////////////////////////////////////
143/// Any other glossary functions go here. Each of them must have a name that
144/// starts with glossary_
145
146function glossary_log_info($log) {
147 global $CFG;
148 return get_record_sql("SELECT g.*, u.firstname, u.lastname
149 FROM {$CFG->prefix}glossary_entries g,
150 {$CFG->prefix}user u
151 WHERE g.glossaryid = '$log->info'
152 AND u.id = '$log->userid'");
153}
154
155function glossary_get_entries($glossaryid, $entrylist) {
156 global $CFG;
157
158 return get_records_sql("SELECT id,userid,concept,definition,format
159 FROM {$CFG->prefix}glossary_entries
160 WHERE glossaryid = '$glossaryid'
161 AND id IN ($entrylist)");
162}
163
164function glossary_print_entry($course, $cm, $glossary, $entry) {
e179048e 165 global $THEME, $USET, $CFG;
166
167 $PermissionGranted = 0;
168 $formatfile = "$CFG->dirroot/mod/glossary/formats/$glossary->displayformat.php";
169 $functionname = "glossary_print_entry_by_format";
170
171 if ( $glossary->displayformat > 0 ) {
172 if ( file_exists($formatfile) ) {
173 include_once($formatfile);
174 if (function_exists($functionname) ) {
175 $PermissionGranted = 1;
176 }
177 }
07842023 178 } else {
e179048e 179 $PermissionGranted = 1;
07842023 180 }
06d94a52 181
e179048e 182 if ( $glossary->displayformat > 0 and $PermissionGranted ) {
183 glossary_print_entry_by_format($course, $cm, $glossary, $entry);
07842023 184 } else {
e179048e 185 glossary_print_entry_by_default($course, $cm, $glossary, $entry);
07842023 186 }
07842023 187
07842023 188}
189
e179048e 190function glossary_print_entry_by_default($course, $cm, $glossary, $entry) {
07842023 191 global $THEME, $USER;
192
193 $colour = $THEME->cellheading2;
194
195 echo "\n<TR>";
e179048e 196 echo "<TD WIDTH=100% BGCOLOR=\"#FFFFFF\">";
197 if ($entry->attachment) {
198 $entry->course = $course->id;
199 echo "<table border=0 align=right><tr><td>";
200 echo glossary_print_attachments($entry,"html");
201 echo "</td></tr></table>";
202 }
203 echo "<b>$entry->concept</b>: ";
07842023 204 echo format_text($entry->definition, $entry->format);
205 glossary_print_entry_icons($course, $cm, $glossary, $entry);
206 echo "</td>";
207 echo "</TR>";
208}
209
210function glossary_print_entry_icons($course, $cm, $glossary, $entry) {
211 global $THEME, $USER;
212
213 if (isteacher($course->id) or $glossary->studentcanpost and $entry->userid == $USER->id) {
214 echo "<p align=right>";
215 if (isteacher($course->id) and !$glossary->mainglossary) {
216 $mainglossary = get_record("glossary","mainglossary",1,"course",$course->id);
217 if ( $mainglossary ) {
07842023 218
219 echo "<a href=\"exportentry.php?id=$cm->id&entry=$entry->id\"><img alt=\"" . get_string("exporttomainglossary","glossary") . "\"src=\"export.gif\" height=11 width=11 border=0></a> ";
220
221 }
222 }
223 echo "<a href=\"deleteentry.php?id=$cm->id&mode=delete&entry=$entry->id\"><img alt=\"" . get_string("delete") . "\"src=\"../../pix/t/delete.gif\" height=11 width=11 border=0></a> ";
224 echo "<a href=\"edit.php?id=$cm->id&e=$entry->id\"><img alt=\"" . get_string("edit") . "\" src=\"../../pix/t/edit.gif\" height=11 width=11 border=0></a>";
225 }
226}
227
228function glossary_search_entries($searchterms, $glossary, $includedefinition) {
229/// Returns a list of entries found using an array of search terms
230/// eg word +word -word
231///
232
233 global $CFG;
234
235 if (!isteacher($glossary->course)) {
236 $glossarymodule = get_record("modules", "name", "glossary");
6a22879b 237 $onlyvisible = " AND g.id = cm.instance AND cm.visible = 1 AND cm.module = $glossarymodule->id";
07842023 238 $onlyvisibletable = ", {$CFG->prefix}course_modules cm";
239 } else {
240
241 $onlyvisible = "";
242 $onlyvisibletable = "";
243 }
244
245 /// Some differences in syntax for PostgreSQL
246 if ($CFG->dbtype == "postgres7") {
247 $LIKE = "ILIKE"; // case-insensitive
248 $NOTLIKE = "NOT ILIKE"; // case-insensitive
249 $REGEXP = "~*";
250 $NOTREGEXP = "!~*";
251 } else {
252 $LIKE = "LIKE";
253 $NOTLIKE = "NOT LIKE";
254 $REGEXP = "REGEXP";
255 $NOTREGEXP = "NOT REGEXP";
256 }
257
258 $conceptsearch = "";
259 $definitionsearch = "";
260
261
262 foreach ($searchterms as $searchterm) {
263 if (strlen($searchterm) < 2) {
264 continue;
265 }
266 if ($conceptsearch) {
267 $conceptsearch.= " OR ";
268 }
269 if ($definitionsearch) {
270 $definitionsearch.= " OR ";
271 }
272
273 if (substr($searchterm,0,1) == "+") {
274 $searchterm = substr($searchterm,1);
275 $conceptsearch.= " e.concept $REGEXP '(^|[^a-zA-Z0-9])$searchterm([^a-zA-Z0-9]|$)' ";
276 $definitionsearch .= " e.definition $REGEXP '(^|[^a-zA-Z0-9])$searchterm([^a-zA-Z0-9]|$)' ";
277 } else if (substr($searchterm,0,1) == "-") {
278 $searchterm = substr($searchterm,1);
279 $conceptsearch .= " e.concept $NOTREGEXP '(^|[^a-zA-Z0-9])$searchterm([^a-zA-Z0-9]|$)' ";
280 $definitionsearch .= " e.definition $NOTREGEXP '(^|[^a-zA-Z0-9])$searchterm([^a-zA-Z0-9]|$)' ";
281 } else {
282 $conceptsearch .= " e.concept $LIKE '%$searchterm%' ";
283 $definitionsearch .= " e.definition $LIKE '%$searchterm%' ";
284 }
285 }
286
287 if ( !$includedefinition ) {
288 $definitionsearch = "0";
289 }
290
291 $selectsql = "{$CFG->prefix}glossary_entries e,
292 {$CFG->prefix}glossary g $onlyvisibletable
293 WHERE ($conceptsearch OR $definitionsearch)
294 AND e.glossaryid = g.id $onlyvisible
295 AND g.id = $glossary->id";
296
297 $totalcount = count_records_sql("SELECT COUNT(*) FROM $selectsql");
298
299 return get_records_sql("SELECT e.concept, e.definition, e.userid, e.timemodified, e.id, e.format FROM
300 $selectsql ORDER BY e.concept ASC $limit");
301}
302
303function glossary_get_participants($glossaryid) {
304//Returns the users with data in one glossary
305//(users with records in glossary_entries, students)
306
307 global $CFG;
308
309 //Get students
310 $students = get_records_sql("SELECT DISTINCT u.*
311 FROM {$CFG->prefix}user u,
312 {$CFG->prefix}glossary_entries g
313 WHERE g.glossaryid = '$glossaryid' and
314 u.id = g.userid");
315
316 //Return students array (it contains an array of unique users)
317 return ($students);
318}
319
e179048e 320
321function glossary_file_area_name($entry) {
322// Creates a directory file name, suitable for make_upload_directory()
323 global $CFG;
324
325 return "$entry->course/$CFG->moddata/glossary/$entry->glossaryid/$entry->id";
326}
327
328function glossary_file_area($entry) {
329 return make_upload_directory( glossary_file_area_name($entry) );
330}
331
332function glossary_delete_old_attachments($entry, $exception="") {
333// Deletes all the user files in the attachments area for a entry
334// EXCEPT for any file named $exception
335
336 if ($basedir = glossary_file_area($entry)) {
337 if ($files = get_directory_list($basedir)) {
338 foreach ($files as $file) {
339 if ($file != $exception) {
340 unlink("$basedir/$file");
341// notify("Existing file '$file' has been deleted!");
342 }
343 }
344 }
345 if (!$exception) { // Delete directory as well, if empty
346 rmdir("$basedir");
347 }
348 }
349}
350
351function glossary_copy_attachments($entry, $newentry) {
352/// Given a entry object that is being copied to glossaryid,
353/// this function checks that entry
354/// for attachments, and if any are found, these are
355/// copied to the new glossary directory.
356
357 global $CFG;
358
359 $return = true;
360
361 if ($entries = get_records_select("glossary_entries", "id = '$entry->id' AND attachment <> ''")) {
362 foreach ($entries as $curentry) {
363 $oldentry->id = $entry->id;
364 $oldentry->course = $entry->course;
365 $oldentry->glossaryid = $curentry->glossaryid;
366 $oldentrydir = "$CFG->dataroot/".glossary_file_area_name($oldentry);
367 if (is_dir($oldentrydir)) {
368
369 $newentrydir = glossary_file_area($newentry);
370 if (! copy("$oldentrydir/$newentry->attachment", "$newentrydir/$newentry->attachment")) {
371 $return = false;
372 }
373 }
374 }
375 }
376 return $return;
377}
378
379function glossary_move_attachments($entry, $glossaryid) {
380/// Given a entry object that is being moved to glossaryid,
381/// this function checks that entry
382/// for attachments, and if any are found, these are
383/// moved to the new glossary directory.
384
385 global $CFG;
386
387 $return = true;
388
389 if ($entries = get_records_select("glossary_entries", "glossaryid = '$entry->id' AND attachment <> ''")) {
390 foreach ($entries as $entry) {
391 $oldentry->course = $entry->course;
392 $oldentry->glossaryid = $entry->glossaryid;
393 $oldentrydir = "$CFG->dataroot/".glossary_file_area_name($oldentry);
394 if (is_dir($oldentrydir)) {
395 $newentry = $oldentry;
396 $newentry->glossaryid = $glossaryid;
397 $newentrydir = "$CFG->dataroot/".glossary_file_area_name($newentry);
398 if (! @rename($oldentrydir, $newentrydir)) {
399 $return = false;
400 }
401 }
402 }
403 }
404 return $return;
405}
406
407function glossary_add_attachment($entry, $newfile) {
408// $entry is a full entry record, including course and glossary
409// $newfile is a full upload array from $_FILES
410// If successful, this function returns the name of the file
411
412 global $CFG;
413
414 if (empty($newfile['name'])) {
415 return "";
416 }
417
418 $newfile_name = clean_filename($newfile['name']);
419
420 if (valid_uploaded_file($newfile)) {
421 if (! $newfile_name) {
422 notify("This file had a wierd filename and couldn't be uploaded");
423
424 } else if (! $dir = glossary_file_area($entry)) {
425 notify("Attachment could not be stored");
426 $newfile_name = "";
427
428 } else {
429 if (move_uploaded_file($newfile['tmp_name'], "$dir/$newfile_name")) {
430 chmod("$dir/$newfile_name", $CFG->directorypermissions);
431 glossary_delete_old_attachments($entry, $newfile_name);
432 } else {
433 notify("An error happened while saving the file on the server");
434 $newfile_name = "";
435 }
436 }
437 } else {
438 $newfile_name = "";
439 }
440
441 return $newfile_name;
442}
443
444function glossary_print_attachments($entry, $return=NULL) {
445// if return=html, then return a html string.
446// if return=text, then return a text-only string.
447// otherwise, print HTML for non-images, and return image HTML
448
449 global $CFG;
450
451 $filearea = glossary_file_area_name($entry);
452
453 $imagereturn = "";
454 $output = "";
455
456 if ($basedir = glossary_file_area($entry)) {
457 if ($files = get_directory_list($basedir)) {
458 $strattachment = get_string("attachment", "glossary");
459 $strpopupwindow = get_string("popupwindow");
460 foreach ($files as $file) {
461 $icon = mimeinfo("icon", $file);
462 if ($CFG->slasharguments) {
463 $ffurl = "file.php/$filearea/$file";
464 } else {
465 $ffurl = "file.php?file=/$filearea/$file";
466 }
467 $image = "<img border=0 src=\"$CFG->wwwroot/files/pix/$icon\" height=16 width=16 alt=\"$strpopupwindow\">";
468
469 if ($return == "html") {
470 $output .= "<a target=_image href=\"$CFG->wwwroot/$ffurl\">$image</a> ";
471 $output .= "<a target=_image href=\"$CFG->wwwroot/$ffurl\">$file</a><br />";
472 } else if ($return == "text") {
473 $output .= "$strattachment $file:\n$CFG->wwwroot/$ffurl\n";
474
475 } else {
476 if ($icon == "image.gif") { // Image attachments don't get printed as links
477 $imagereturn .= "<br /><img src=\"$CFG->wwwroot/$ffurl\">";
478 } else {
479 link_to_popup_window("/$ffurl", "attachment", $image, 500, 500, $strattachment);
480 echo "<a target=_image href=\"$CFG->wwwroot/$ffurl\">$file</a>";
481 echo "<br />";
482 }
483 }
484 }
485 }
486 }
487
488 if ($return) {
489 return $output;
490 }
491
492 return $imagereturn;
493}
494
06d94a52 495function print_tabbed_table_start($data, $CurrentTab, $tTHEME = NULL) {
496
497if ( !$tTHEME ) {
498 global $THEME;
499 $tTHEME = $THEME;
500}
501
502$TableColor = $tTHEME->TabTableBGColor;
503$TableWidth = $tTHEME->TabTableWidth;
504$CurrentTabColor = $tTHEME->ActiveTabColor;
505$TabColor = $tTHEME->InactiveTabColor;
506$TabsPerRow = $tTHEME->TabsPerRow;
507$TabSeparation = $tTHEME->TabSeparation;
508
509$Tabs = count($data);
510$TabWidth = (int) (100 / $TabsPerRow);
511
512$CurrentRow = ( $CurrentTab - ( $CurrentTab % $TabsPerRow) ) / $TabsPerRow;
513
514$NumRows = (int) ( $Tabs / $TabsPerRow ) + 1;
515
516?>
517 <center>
518 <table border="0" cellpadding="0" cellspacing="0" width="<? p($TableWidth) ?>">
519 <tr>
520 <td width="100%">
521
522 <table border="0" cellpadding="0" cellspacing="0" width="100%">
523
524<?
525$TabProccessed = 0;
526for ($row = 0; $row < $NumRows; $row++) {
527 echo "<tr>\n";
528 if ( $row != $CurrentRow ) {
529 for ($col = 0; $col < $TabsPerRow; $col++) {
530 if ( $TabProccessed < $Tabs ) {
531 if ($TabProccessed == $CurrentTab) {
532 $CurrentColor = $CurrentTabColor;
533 } else {
534 $CurrentColor = $TabColor;
535 }
536 ?>
537 <td width="<? p($TabWidth) ?>%" bgcolor="<? p($CurrentColor) ?>" align="center">
538 <b><a href="<? p($data[$TabProccessed]->link) ?>"><? p($data[$TabProccessed]->caption) ?></a></b></td>
539 <? if ($col < $TabsPerRow) { ?>
540 <td width="<? p($TabSeparation) ?>" align="center">&nbsp;</td>
541 <? }
542 } else {
543 $CurrentColor = "";
544 }
545 $TabProccessed++;
546 }
547 } else {
548 $FirstTabInCurrentRow = $TabProccessed;
549 $TabProccessed += $TabsPerRow;
550 }
551 echo "</tr><tr><td colspan=" . (2* $TabsPerRow) . " ></td></tr>\n";
552}
553 echo "<tr>\n";
554 $TabProccessed = $FirstTabInCurrentRow;
555 for ($col = 0; $col < $TabsPerRow; $col++) {
556 if ( $TabProccessed < $Tabs ) {
557 if ($TabProccessed == $CurrentTab) {
558 $CurrentColor = $CurrentTabColor;
559 } else {
560 $CurrentColor = $TabColor;
561 }
562 ?>
563 <td width="<? p($TabWidth) ?>%" bgcolor="<? p($CurrentColor) ?>" align="center">
564 <b><a href="<? p($data[$TabProccessed]->link) ?>"><? p($data[$TabProccessed]->caption) ?></a></b></td>
565 <? if ($col < $TabsPerRow) { ?>
566 <td width="<? p($TabSeparation) ?>" align="center">&nbsp;</td>
567 <? }
568 } else {
569 if ($NumRows > 1) {
570 $CurrentColor = $TabColor;
571 } else {
572 $CurrentColor = "";
573 }
574 echo "<td colspan = " . (2 * ($TabsPerRow - $col)) . " bgcolor=\"$CurrentColor\" align=\"center\">";
575 echo "</td>";
576
577 $col = $TabsPerRow;
578 }
579 $TabProccessed++;
580 }
581 echo "</tr>\n";
582 ?>
583
584 </table>
585 </td>
586 </tr>
587 <tr>
588 <td width="100%" bgcolor="<? p($TableColor) ?>"><hr></td>
589 </tr>
590 <tr>
591 <td width="100%" bgcolor="<? p($TableColor) ?>">
592 <center>
593<?
594}
595
596function print_tabbed_table_end() {
597 echo "</center><p></td></tr></table></center>";
598}
599
e179048e 600?>