MDL-14679 fixed references to mod.html
[moodle.git] / mod / wiki / lib.php
1 <?php  // $Id$
3 /// Library of functions and constants for module wiki
4 /// (replace wiki with the name of your module and delete this line)
7 $wiki_CONSTANT = 7;     /// for example
8 $site = get_site();
9 $WIKI_TYPES = array ('teacher' =>   get_string('defaultcourseteacher'),
10                      'group' =>     get_string('groups',"wiki"),
11                      'student' =>   get_string('defaultcoursestudent') );
12 define("EWIKI_ESCAPE_AT", 0);       # For the algebraic filter
14 // How long locks stay around without being confirmed (seconds)
15 define("WIKI_LOCK_PERSISTENCE",120);
17 // How often to confirm that you still want a lock
18 define("WIKI_LOCK_RECONFIRM",60);
20 // Session variable used to store wiki locks
21 define('SESSION_WIKI_LOCKS','wikilocks');
23 /*** Moodle 1.7 compatibility functions *****
24  *
25  ********************************************/
26 function wiki_context($wiki) {
27     //TODO: add some $cm caching if needed
28     if (is_object($wiki)) {
29         $wiki = $wiki->id;
30     }
31     if (! $cm = get_coursemodule_from_instance('wiki', $wiki)) {
32         print_error('Course Module ID was incorrect');
33     }
35     return get_context_instance(CONTEXT_MODULE, $cm->id);
36 }
38 function wiki_is_teacher($wiki, $userid=NULL) {
39     return has_capability('mod/wiki:manage', wiki_context($wiki), $userid);
40 }
42 function wiki_is_teacheredit($wiki, $userid=NULL) {
43     return has_capability('mod/wiki:manage', wiki_context($wiki), $userid)
44        and has_capability('moodle/site:accessallgroups', wiki_context($wiki), $userid);
45 }
47 function wiki_is_student($wiki, $userid=NULL) {
48     return has_capability('mod/wiki:participate', wiki_context($wiki), $userid);
49 }
51 function wiki_get_students($wiki, $groups='', $sort='u.lastaccess', $fields='u.*') {
52     return $users = get_users_by_capability(wiki_context($wiki), 'mod/wiki:participate', $fields, $sort, '', '', $groups);
53 }
55 /* end of compatibility functions */
58 function wiki_add_instance($wiki) {
59 /// Given an object containing all the necessary data,
60 /// (defined by the form in mod_form.php) this function
61 /// will create a new instance and return the id number
62 /// of the new instance.
64     $wiki->timemodified = time();
66     # May have to add extra stuff in here #
68     /// Determine the pagename for this wiki and save.
69     $wiki->pagename = wiki_page_name($wiki);
71     return insert_record("wiki", $wiki);
72 }
75 function wiki_update_instance($wiki) {
76 /// Given an object containing all the necessary data,
77 /// (defined by the form in mod_form.php) this function
78 /// will update an existing instance with new data.
80     /// Determine the pagename for this wiki.
81     $wiki->pagename = wiki_page_name($wiki);
83     $wiki->timemodified = time();
84     $wiki->id = $wiki->instance;
85     return update_record("wiki", $wiki);
86 }
88 /// Delete all Directories recursively
89 function wiki_rmdir($basedir) {
90   $handle = @opendir($basedir);
91   if($handle) {
92     while (false!==($folder = readdir($handle))) {
93        if($folder != "." && $folder != ".." && $folder != "CVS") {
94           wiki_rmdir("$basedir/$folder");  // recursive
95        }
96     }
97     closedir($handle);
98   }
99   @rmdir($basedir);
102 function wiki_delete_instance($id) {
103 /// Given an ID of an instance of this module,
104 /// this function will permanently delete the instance
105 /// and any data that depends on it.
106     global $CFG;
108     if (! $wiki = get_record("wiki", "id", $id)) {
109         return false;
110     }
112     $result = true;
114     #Delete Files
115 ### Should probably check regardless of this setting in case its been changed...
116     if($wiki->ewikiacceptbinary) {
117       if ($basedir = $CFG->dataroot."/".$wiki->course."/".$CFG->moddata."/wiki/$id") {
118           if ($files = get_directory_list($basedir)) {
119               foreach ($files as $file) {
120                   #if ($file != $exception) {
121                       unlink("$basedir/$file");
122                       notify("Existing file '$file' has been deleted!");
123                   #}
124               }
125           }
126           #if (!$exception) {  // Delete directory as well, if empty
127               wiki_rmdir("$basedir");
128           #}
129       }
130     }
132     # Delete any dependent records here #
133     if(!delete_records("wiki_locks","wikiid",$wiki->id)) {
134         $result = false;
135     }
137     if (! delete_records("wiki", "id", $wiki->id)) {
138         $result = false;
139     }
141     /// Delete all wiki_entries and wiki_pages.
142     if (($wiki_entries = wiki_get_entries($wiki)) !== false) {
143         foreach ($wiki_entries as $wiki_entry) {
144             if (! delete_records("wiki_pages", "wiki", "$wiki_entry->id")) {
145                 $result = false;
146             }
147             if (! delete_records("wiki_entries", "id", "$wiki_entry->id")) {
148                 $result = false;
149             }
150         }
151     }
153     return $result;
156 function wiki_user_outline($course, $user, $mod, $wiki) {
157 /// Return a small object with summary information about what a
158 /// user has done with a given particular instance of this module
159 /// Used for user activity reports.
160 /// $return->time = the time they did it
161 /// $return->info = a short text description
163     $return = NULL;
164     return $return;
167 function wiki_user_complete($course, $user, $mod, $wiki) {
168 /// Print a detailed representation of what a  user has done with
169 /// a given particular instance of this module, for user activity reports.
171     return true;
174 function wiki_print_recent_activity($course, $isteacher, $timestart) {
175 /// Given a course and a time, this module should find recent activity
176 /// that has occurred in wiki activities and print it out.
177 /// Return true if there was output, or false is there was none.
179     global $CFG;
180     
181     $sql = "SELECT l.*, cm.instance FROM {$CFG->prefix}log l 
182                 INNER JOIN {$CFG->prefix}course_modules cm ON l.cmid = cm.id 
183             WHERE l.time > '$timestart' AND l.course = {$course->id} 
184                 AND l.module = 'wiki' AND action LIKE 'edit%'
185             ORDER BY l.time ASC";
186             
187     if (!$logs = get_records_sql($sql)){
188         return false;
189     }
191     $modinfo = get_fast_modinfo($course);
192     $wikis = array();
194     foreach ($logs as $log) {
195         $cm = $modinfo->instances['wiki'][$log->instance];
196         if (!$cm->uservisible) {
197             continue;
198         }
200         $wikis[$log->info] = wiki_log_info($log);
201         $wikis[$log->info]->pagename = $log->info;
202         $wikis[$log->info]->time = $log->time;
203         $wikis[$log->info]->url  = str_replace('&', '&amp;', $log->url);
204     }
206     if (!$wikis) {
207         return false;
208     }
209     print_headline(get_string('updatedwikipages', 'wiki').':', 3);
210     foreach ($wikis as $wiki) {
211         print_recent_activity_note($wiki->time, $wiki, $wiki->pagename,
212                                    $CFG->wwwroot.'/mod/wiki/'.$wiki->url);
213     }
215     return false;
218 function wiki_log_info($log) {
219     global $CFG;
220     return get_record_sql("SELECT u.firstname, u.lastname
221                              FROM {$CFG->prefix}user u
222                             WHERE u.id = '$log->userid'");
225 function wiki_cron () {
226 /// Function to be run periodically according to the moodle cron
227 /// This function searches for things that need to be done, such
228 /// as sending out mail, toggling flags etc ...
230     // Delete expired locks
231     $result=delete_records_select('wiki_locks','lockedseen < '.(time()-WIKI_LOCK_PERSISTENCE));
233     return $result;
236 function wiki_grades($wikiid) {
237 /// Must return an array of grades for a given instance of this module,
238 /// indexed by user.  It also returns a maximum allowed grade.
240     return NULL;
243 function wiki_get_participants($wikiid) {
244 //Returns the users with data in one wiki
245 //(users with records in wiki_pages and wiki_entries)
247     global $CFG;
249     //Get users from wiki_pages
250     $st_pages = get_records_sql("SELECT DISTINCT u.id, u.id
251                                  FROM {$CFG->prefix}user u,
252                                       {$CFG->prefix}wiki_entries e,
253                                       {$CFG->prefix}wiki_pages p
254                                  WHERE e.wikiid = '$wikiid' and
255                                        p.wiki = e.id and
256                                        u.id = p.userid");
258     //Get users from wiki_entries
259     $st_entries = get_records_sql("SELECT DISTINCT u.id, u.id
260                                    FROM {$CFG->prefix}user u,
261                                         {$CFG->prefix}wiki_entries e
262                                    WHERE e.wikiid = '$wikiid' and
263                                          u.id = e.userid");
265     //Add entries to pages
266     if ($st_entries) {
267         foreach ($st_entries as $st_entry) {
268             $st_pages[$st_entry->id] = $st_entry;
269         }
270     }
272     return $st_pages;
276 //////////////////////////////////////////////////////////////////////////////////////
277 /// Any other wiki functions go here.  Each of them must have a name that
278 /// starts with wiki_
280 function wiki_wiki_name($wikiname) {
281 /// Return the passed in string in Wiki name format.
282 /// Remove any leading and trailing whitespace, capitalize all the words
283 /// and then remove any internal whitespace.
285     if (wiki_is_wiki_name($wikiname)) {
286         return $wikiname;
287     }
288     else {
289         /// Create uppercase words and remove whitespace.
290         $wikiname = preg_replace("/(\w+)\s/", "$1", ucwords(trim($wikiname)));
292         /// Check again - there may only be one word.
293         if (wiki_is_wiki_name($wikiname)) {
294             return $wikiname;
295         }
296         /// If there is only one word, append default wiki name to it.
297         else {
298             return $wikiname.get_string('wikidefaultpagename', 'wiki');
299         }
300     }
303 function wiki_is_wiki_name($wikiname) {
304 /// Check for correct wikiname syntax and return true or false.
306     /// If there are spaces between the words, incorrect format.
307     if (preg_match_all('/\w+/', $wikiname, $out) > 1) {
308         return false;
309     }
310     /// If there isn't more than one group of uppercase letters separated by
311     /// lowercase letters or '_', incorrect format.
312     else if (preg_match_all('/[A-Z]+[a-z_]+/', $wikiname, $out) > 1) {
313         return true;
314     }
315     else {
316         return false;
317     }
320 function wiki_page_name(&$wiki) {
321 /// Determines the wiki's page name and returns it.
322     if (!empty($wiki->initialcontent)) {
323         $ppos = strrpos($wiki->initialcontent, '/');
324         if ($ppos === false) {
325             $pagename = $wiki->initialcontent;
326         }
327         else {
328             $pagename = substr($wiki->initialcontent, $ppos+1);
329         }
330     }
331     else if (!empty($wiki->pagename)) {
332         $pagename = $wiki->pagename;
333     }
334     else {
335         $pagename = $wiki->name;
336     }
337     return $pagename;
340 function wiki_content_dir(&$wiki) {
341 /// Determines the wiki's default content directory (if there is one).
342     global $CFG;
344     if (!empty($wiki->initialcontent)) {
345         $ppos = strrpos($wiki->initialcontent, '/');
346         if ($ppos === false) {
347             $subdir = '';
348         }
349         else {
350             $subdir = substr($wiki->initialcontent, 0, $ppos+1);
351         }
352         $contentdir = $CFG->dataroot.'/'.$wiki->course.'/'.$subdir;
353     }
354     else {
355         $contentdir = false;
356     }
357     return $contentdir;
360 function wiki_get_course_wikis($courseid, $wtype='*') {
361 /// Returns all wikis for the specified course and optionally of the specified type.
363     $select = 'course = '.$courseid;
364     if ($wtype != '*') {
365         $select .= ' AND wtype = \''.$wtype.'\'';
366     }
367     return get_records_select('wiki', $select, 'id');
370 function wiki_has_entries(&$wiki) {
371 /// Returns true if wiki already has wiki entries; otherwise false.
373     return record_exists('wiki_entries', 'wikiid', $wiki->id);
376 function wiki_get_entries(&$wiki, $byindex=NULL) {
377 /// Returns an array with all wiki entries indexed by entry id; false if there are none.
378 /// If the optional $byindex is specified, returns the entries indexed by that field.
379 /// Valid values for $byindex are 'student', 'group'.
380     global $CFG;
381     
382     if ($byindex == 'student') {
383         return get_records('wiki_entries', 'wikiid', $wiki->id, '',
384                            'userid,id,wikiid,course,groupid,pagename,timemodified');
385     }
386     else if ($byindex == 'group') {
387         return get_records('wiki_entries', 'wikiid', $wiki->id, '',
388                            'groupid,id,wikiid,course,userid,pagename,timemodified');
389     }
390     else {
391         return get_records('wiki_entries', 'wikiid', $wiki->id);
392     }
395 function wiki_get_default_entry(&$wiki, &$course, $userid=0, $groupid=0) {
396 /// Returns the wiki entry according to the wiki type.
397 /// Optionally, will return wiki entry for $userid student wiki, or
398 /// $groupid group or teacher wiki.
399 /// Creates one if it needs to and it can.
400     global $USER;
401     /// If there is a groupmode, get the user's group id.
402     $groupmode = groups_get_activity_groupmode($wiki);
403     // if groups mode is in use and no group supplied, use the first one found
404     if ($groupmode && !$groupid) {
405         if(($mygroupids=mygroupid($course->id)) && count($mygroupids)>0) {
406             // Use first group. They ought to be able to change later
407             $groupid=$mygroupids[0];
408         } else {
409             // Whatever groups are in the course, pick one
410             $coursegroups = groups_get_all_groups($course->id);
411             if(!$coursegroups || count($coursegroups)==0) {
412                 print_error("Can't access wiki in group mode when no groups are configured for the course");
413             }
414             $unkeyed=array_values($coursegroups); // Make sure first item is index 0
415             $groupid=$unkeyed[0]->id;
416         }
417     }
419     /// If the wiki entry doesn't exist, can this user create it?
420     if (($wiki_entry = wiki_get_entry($wiki, $course, $userid, $groupid)) === false) {
421         if (wiki_can_add_entry($wiki, $USER, $course, $userid, $groupid)) {
422             wiki_add_entry($wiki, $course, $userid, $groupid);
423             if (($wiki_entry = wiki_get_entry($wiki, $course, $userid, $groupid)) === false) {
424                 print_error("Could not add wiki entry.");
425             }
426         }
427     }
428     //print_object($wiki_entry);
429     return $wiki_entry;
432 function wiki_get_entry(&$wiki, &$course, $userid=0, $groupid=0) {
433 /// Returns the wiki entry according to the wiki type.
434 /// Optionally, will return wiki entry for $userid student wiki, or
435 /// $groupid group or teacher wiki.
436     global $USER;
438     switch ($wiki->wtype) {
439     case 'student':
440         /// If a specific user was requested, return it, if allowed.
441         if ($userid and wiki_user_can_access_student_wiki($wiki, $userid, $course)) {
442             $wentry = wiki_get_student_entry($wiki, $userid);
443         }
445         /// If there is no entry for this user, check if this user is a teacher.
446         else if (!$wentry = wiki_get_student_entry($wiki, $USER->id)) {
447 /*            if (wiki_is_teacher($wiki, $USER->id)) {
448                 /// If this user is a teacher, return the first entry.
449                 if ($wentries = wiki_get_entries($wiki)) {
450                     $wentry = current($wentries);
451                 }
452             }*/
453         }
454         break;
456     case 'group':
457         /// If there is a groupmode, get the user's group id.
458         $groupmode = groups_get_activity_groupmode($wiki);
459         if($groupmode) {
460             if(!$groupid) {
461                 if(($mygroupids=mygroupid($course->id)) && count($mygroupids)>0) {
462                     // Use first group. They ought to be able to change later
463                     $groupid=$mygroupids[0];
464                 } else {
465                     // Whatever groups are in the course, pick one
466                     $coursegroups = groups_get_all_groups($course->id);
467                     if(!$coursegroups || count($coursegroups)==0) {
468                         print_error("Can't access wiki in group mode when no groups are configured for the course");
469                     }
470                     $unkeyed=array_values($coursegroups); // Make sure first item is index 0
471                     $groupid=$unkeyed[0]->id;
472                 }
473             }
475             //echo "groupid is in wiki_get_entry ".$groupid."<br />";
476             /// If a specific group was requested, return it, if allowed.
477             if ($groupid and wiki_user_can_access_group_wiki($wiki, $groupid, $course)) {
478                 $wentry = wiki_get_group_entry($wiki, $groupid);
479             } else {
480                 print_error("Cannot access any groups for this wiki");
481             }
482         }
483         /// If mode is 'nogroups', then groupid is zero.
484         else {
485             $wentry = wiki_get_group_entry($wiki, 0);
486         }
487         break;
489     case 'teacher':
490         /// If there is a groupmode, get the user's group id.
491         if (groupmode($course, $wiki)) {
492             $mygroupids = mygroupid($course->id);//same here, default to the first one
493             $groupid = $groupid ? $groupid : $mygroupids[0]/*mygroupid($course->id)*/;
494         }
496         /// If a specific group was requested, return it, if allowed.
497         if (wiki_user_can_access_teacher_wiki($wiki, $groupid, $course)) {
498             $wentry = wiki_get_teacher_entry($wiki, $groupid);
499         }
500         break;
501     }
502     return $wentry;
505 function wiki_get_teacher_entry(&$wiki, $groupid=0) {
506 /// Returns the wiki entry for the wiki teacher type.
507     return get_record('wiki_entries', 'wikiid', $wiki->id, 'course', $wiki->course, 'groupid', $groupid);
510 function wiki_get_group_entry(&$wiki, $groupid=null) {
511 /// Returns the wiki entry for the given group.
512     return get_record('wiki_entries', 'wikiid', $wiki->id, 'groupid', $groupid);
515 function wiki_get_student_entry(&$wiki, $userid=null) {
516 /// Returns the wiki entry for the given student.
517     global $USER;
519     if (is_null($userid)) {
520         $userid = $USER->id;
521     }
522     return get_record('wiki_entries', 'wikiid', $wiki->id, 'userid', $userid);
525 function wiki_get_other_wikis(&$wiki, &$user, &$course, $currentid=0) {
526     /// Returns a list of other wikis to display, depending on the type, group and user.
527     /// Returns the key containing the currently selected entry as well.
529     global $CFG, $id;
531     $wikis = false;
533     $groupmode = groups_get_activity_groupmode($wiki);
534     $mygroupid = mygroupid($course->id);
535     $isteacher = wiki_is_teacher($wiki, $user->id);
536     $isteacheredit = wiki_is_teacheredit($wiki, $user->id);
538     $groupingid = null;
539     $cm = new stdClass;
540     $cm->id = $wiki->cmid;
541     $cm->groupmode = $wiki->groupmode;
542     $cm->groupingid = $wiki->groupingid;
543     $cm->groupmembersonly = $wiki->groupmembersonly;
544     if (!empty($CFG->enablegroupings) && !empty($cm->groupingid)) {
545         $groupingid = $wiki->groupingid;
546     }
547     
548     
549     switch ($wiki->wtype) {
551     case 'student':
552         /// Get all the existing entries for this wiki.
553         $wiki_entries = wiki_get_entries($wiki, 'student');
554         
555         if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
556             $sql = "SELECT gm.userid FROM {$CFG->prefix}groups_members gm " .
557                     "INNER JOIN {$CFG->prefix}groupings_groups gg ON gm.groupid = gg.groupid " .
558                     "WHERE gg.groupingid = $wiki->groupingid ";
559     
560             $groupingmembers = get_records_sql($sql);
561         }
562         
563         if ($isteacher and (SITEID != $course->id)) {
565             /// If the user is an editing teacher, or a non-editing teacher not assigned to a group, show all student
566             /// wikis, regardless of creation.
567             if ((SITEID != $course->id) and ($isteacheredit or ($groupmode == NOGROUPS))) {
568                 if ($students = get_users_by_capability(get_context_instance(CONTEXT_COURSE, $course->id), 'moodle/course:view', '', '', '', '', '', '', false)) {
569                     /// Default pagename is dependent on the wiki settings.
570                     $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
572                     foreach ($students as $student) {
573                         if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid) && empty($groupingmembers[$student->id])) {
574                             continue;
575                         }
576                         /// If this student already has an entry, use its pagename.
577                         if ($wiki_entries[$student->id]) {
578                             $pagename = $wiki_entries[$student->id]->pagename;
579                         }
580                         else {
581                             $pagename = $defpagename;
582                         }
584                         $key = 'view.php?id='.$id.'&userid='.$student->id.'&page='.$pagename;
585                         $wikis[$key] = fullname($student).':'.$pagename;
586                     }
587                 }
588             }
589             else if ($groupmode == SEPARATEGROUPS) {
591                 if ($students = wiki_get_students($wiki, $mygroupid)) {
592                     $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
593                     foreach ($students as $student) {
594                         if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid) && empty($groupingmembers[$student->id])) {
595                             continue;
596                         }
597                         /// If this student already has an entry, use its pagename.
598                         if ($wiki_entries[$student->id]) {
599                             $pagename = $wiki_entries[$student->id]->pagename;
600                         }
601                         else {
602                             $pagename = $defpagename;
603                         }
605                         $key = 'view.php?id='.$id.'&userid='.$student->id.'&page='.$pagename;
606                         $wikis[$key] = fullname($student).':'.$pagename;
607                     }
608                 }
609             }
610             else if ($groupmode == VISIBLEGROUPS) {
611                 /// Get all students in your group.
612                 if ($students = wiki_get_students($wiki, $mygroupid)) {
613                     $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
614                     foreach ($students as $student) {
615                         if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid) && empty($groupingmembers[$student->id])) {
616                             continue;
617                         }
618                         /// If this student already has an entry, use its pagename.
619                         if ($wiki_entries[$student->id]) {
620                             $pagename = $wiki_entries[$student->id]->pagename;
621                         }
622                         else {
623                             $pagename = $defpagename;
624                         }
625                         $key = 'view.php?id='.$id.'&userid='.$student->id.'&page='.$pagename;
626                         $wikis[$key] = fullname($student).':'.$pagename;
627                     }
628                 }
629                 /// Get all student wikis created, regardless of group.
630                 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
631                     $sql = 'SELECT w.id, w.userid, w.pagename, u.firstname, u.lastname '
632                           .'    FROM '.$CFG->prefix.'wiki_entries w '
633                           .'    INNER JOIN '.$CFG->prefix.'user u ON w.userid = u.id '
634                           .'    INNER JOIN '.$CFG->prefix.'groups_members gm ON gm.userid = u.id '
635                           .'    INNER JOIN '.$CFG->prefix.'groupings_groups gg ON gm.groupid = gg.groupid '
636                           .'    WHERE w.wikiid = '.$wiki->id.' AND gg.groupingid =  '.$wiki->groupingid
637                           .'    ORDER BY w.id';
638                 } else {
639                     $sql = 'SELECT w.id, w.userid, w.pagename, u.firstname, u.lastname '
640                           .'    FROM '.$CFG->prefix.'wiki_entries w, '.$CFG->prefix.'user u '
641                           .'    WHERE w.wikiid = '.$wiki->id.' AND u.id = w.userid '
642                           .'    ORDER BY w.id';
643                 }
644                 $wiki_entries = get_records_sql($sql);
645                 $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
646                 foreach ($wiki_entries as $wiki_entry) {
647                     $key = 'view.php?id='.$id.'&userid='.$wiki_entry->userid.'&page='.$wiki_entry->pagename;
648                     $wikis[$key] = fullname($wiki_entry).':'.$wiki_entry->pagename;
649                     if ($currentid == $wiki_entry->id) {
650                         $wikis['selected'] = $key;
651                     }
652                 }
653             }
654         }
655         else {
656             /// A user can see other student wikis if they are a member of the same
657             /// group (for separate groups) or there are visible groups, or if this is
658             /// a site-level wiki, and they are an administrator.
659             if (($groupmode == VISIBLEGROUPS) or wiki_is_teacheredit($wiki)) {
660                 $viewall = true;
661             }
662             else if ($groupmode == SEPARATEGROUPS) {
663                 $viewall = mygroupid($course->id);
664             }
665             else {
666                 $viewall = false;
667             }
669             if ($viewall !== false) {
670                 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
671                     $sql = 'SELECT w.id, w.userid, w.pagename, u.firstname, u.lastname '
672                           .'    FROM '.$CFG->prefix.'wiki_entries w '
673                           .'    INNER JOIN '.$CFG->prefix.'user u ON w.userid = u.id '
674                           .'    INNER JOIN '.$CFG->prefix.'groups_members gm ON gm.userid = u.id '
675                           .'    INNER JOIN '.$CFG->prefix.'groupings_groups gg ON gm.groupid = gg.groupid '
676                           .'    WHERE w.wikiid = '.$wiki->id.' AND gg.groupingid =  '.$wiki->groupingid
677                           .'    ORDER BY w.id';
678                 } else {
679                     $sql = 'SELECT w.id, w.userid, w.pagename, u.firstname, u.lastname '
680                           .'    FROM '.$CFG->prefix.'wiki_entries w, '.$CFG->prefix.'user u '
681                           .'    WHERE w.wikiid = '.$wiki->id.' AND u.id = w.userid '
682                           .'    ORDER BY w.id';
683                 }
684                 $wiki_entries = get_records_sql($sql);
685                 $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
686                 foreach ($wiki_entries as $wiki_entry) {
687                     if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid) && empty($groupingmembers[$wiki_entry->userid])) {
688                         continue;
689                     }
690                 
691                     if (($viewall === true) or groups_is_member($viewall, $wiki_entry->userid)) {
692                         $key = 'view.php?id='.$id.'&userid='.$wiki_entry->userid.'&page='.$wiki_entry->pagename;
693                         $wikis[$key] = fullname($wiki_entry).':'.$wiki_entry->pagename;
694                         if ($currentid == $wiki_entry->id) {
695                             $wikis['selected'] = $key;
696                         }
697                     }
698                 }
699             }
700         }
701         break;
703     case 'group':
704         /// If the user is an editing teacher, or a non-editing teacher not assigned to a group, show all group
705         /// wikis, regardless of creation.
707         /// If user is a member of multiple groups, need to show current group etc?
709         /// Get all the existing entries for this wiki.
710         $wiki_entries = wiki_get_entries($wiki, 'group');
711         
712         if ($groupmode and ($isteacheredit or ($isteacher and !$mygroupid))) {
713             if ($groups = groups_get_all_groups($course->id, null, $groupingid)) {
714                 $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
715                 foreach ($groups as $group) {
717                     /// If this group already has an entry, use its pagename.
718                     if (isset($wiki_entries[$group->id])) {
719                         $pagename = $wiki_entries[$group->id]->pagename;
720                     }
721                     else {
722                         $pagename = $defpagename;
723                     }
725                     $key = 'view.php?id='.$id.($group->id?"&groupid=".$group->id:"").'&page='.$pagename;
726                     $wikis[$key] = $group->name.':'.$pagename;
727                 }
728             }
729         }
730         //if a studnet with multiple groups in SPG
731         else if ($groupmode == SEPARATEGROUPS){
732             if ($groups = groups_get_all_groups($course->id, $user->id, $groupingid)){
734                 $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
735                 foreach ($groups as $group) {
736                     /// If this group already has an entry, use its pagename.
737                     if (isset($wiki_entries[$group->id])) {
738                         $pagename = $wiki_entries[$group->id]->pagename;
739                     }
740                     else {
741                         $pagename = $defpagename;
742                     }
743                     $key = 'view.php?id='.$id.($group->id?"&groupid=".$group->id:"").'&page='.$pagename;
744                     $wikis[$key] = $group->name.':'.$pagename;
745                 }
747             }
749         }
750         /// A user can see other group wikis if there are visible groups.
751         else if ($groupmode == VISIBLEGROUPS) {
752             if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
753                 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
754                       .'    FROM '.$CFG->prefix.'wiki_entries w '
755                       .'    INNER JOIN '.$CFG->prefix.'groups g ON g.id = w.groupid '
756                       .'    INNER JOIN '.$CFG->prefix.'groupings_groups gg ON g.id = gg.groupid '
757                       .'    WHERE w.wikiid = '.$wiki->id.' AND gg.groupingid =  '.$wiki->groupingid
758                       .'    ORDER BY w.groupid';
759             } else {
760                 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
761                       .'    FROM '.$CFG->prefix.'wiki_entries w, '.$CFG->prefix.'groups g '
762                       .'    WHERE w.wikiid = '.$wiki->id.' AND g.id = w.groupid '
763                       .'    ORDER BY w.groupid';
764             }
765             $wiki_entries = get_records_sql($sql);
766             $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
767             foreach ($wiki_entries as $wiki_entry) {
768                 $key = 'view.php?id='.$id.($wiki_entry->groupid?"&groupid=".$wiki_entry->groupid:"").'&page='.$wiki_entry->pagename;
769                 $wikis[$key] = $wiki_entry->gname.':'.$wiki_entry->pagename;
770                 if ($currentid == $wiki_entry->id) {
771                     $wikis['selected'] = $key;
772                 }
773             }
774         }
775         break;
777     case 'teacher':
778         if ($isteacher) {
779             /// If the user is an editing teacher, or a non-editing teacher not assigned to a group, show all
780             /// teacher wikis, regardless of creation.
781             if ($groupmode and ($isteacheredit or ($isteacher and !$mygroupid))) {
782                 if ($groups = groups_get_all_groups($course->id, null, $groupingid)) {
783                     $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
784                     foreach ($groups as $group) {
785                         /// If this group already has an entry, use its pagename.
786                         if ($wiki_entries[$group->id]) {
787                             $pagename = $wiki_entries[$group->id]->pagename;
788                         }
789                         else {
790                             $pagename = $defpagename;
791                         }
793                         $key = 'view.php?id='.$id.($group->id?"&groupid=".$group->id:"").'&page='.$pagename;
794                         $wikis[$key] = $group->name.':'.$pagename;
795                     }
796                 }
797             }
798             /// A teacher can see all other group teacher wikis.
799             else if ($groupmode) {
800             if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
801                 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
802                       .'    FROM '.$CFG->prefix.'wiki_entries w '
803                       .'    INNER JOIN '.$CFG->prefix.'groups g ON g.id = w.groupid '
804                       .'    INNER JOIN '.$CFG->prefix.'groupings_groups gg ON g.id = gg.groupid '
805                       .'    WHERE w.wikiid = '.$wiki->id.' AND gg.groupingid =  '.$wiki->groupingid
806                       .'    ORDER BY w.groupid';
807             } else {
808                 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
809                       .'    FROM '.$CFG->prefix.'wiki_entries w, '.$CFG->prefix.'groups g '
810                       .'    WHERE w.wikiid = '.$wiki->id.' AND g.id = w.groupid '
811                       .'    ORDER BY w.groupid';
812             }
813                 $wiki_entries = get_records_sql($sql);
814                 $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
815                 foreach ($wiki_entries as $wiki_entry) {
816                     $key = 'view.php?id='.$id.($wiki_entry->groupid?"&groupid=".$wiki_entry->groupid:"").'&page='.$wiki_entry->pagename;
817                     $wikis[$key] = $wiki_entry->gname.':'.$wiki_entry->pagename;
818                     if ($currentid == $wiki_entry->id) {
819                         $wikis['selected'] = $key;
820                     }
821                 }
822             }
823         }
824         else {
825             /// A user can see other teacher wikis if they are a teacher, a member of the same
826             /// group (for separate groups) or there are visible groups.
827             if ($groupmode == VISIBLEGROUPS) {
828                 $viewall = true;
829             }
830             else if ($groupmode == SEPARATEGROUPS) {
831                 $viewall = $mygroupid;
832             }
833             else {
834                 $viewall = false;
835             }
836             if ($viewall !== false) {
837                 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
838                     $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
839                           .'    FROM '.$CFG->prefix.'wiki_entries w '
840                           .'    INNER JOIN '.$CFG->prefix.'groups g ON g.id = w.groupid '
841                           .'    INNER JOIN '.$CFG->prefix.'groupings_groups gg ON g.id = gg.groupid '
842                           .'    WHERE w.wikiid = '.$wiki->id.' AND gg.groupingid =  '.$wiki->groupingid
843                           .'    ORDER BY w.groupid';
844                 } else {
845                     $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
846                           .'    FROM '.$CFG->prefix.'wiki_entries w, '.$CFG->prefix.'groups g '
847                           .'    WHERE w.wikiid = '.$wiki->id.' AND g.id = w.groupid '
848                           .'    ORDER BY w.groupid';
849                 }
850                 $wiki_entries = get_records_sql($sql);
851                 $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
854                 foreach ($wiki_entries as $wiki_entry) {
855                     if (($viewall === true) or @in_array($wiki_entry->groupid, $viewall)/*$viewall == $wiki_entry->groupid*/) {
856                         $key = 'view.php?id='.$id.($wiki_entry->groupid?"&groupid=".$wiki_entry->groupid:"").'&page='.$wiki_entry->pagename;
857                         $wikis[$key] = $wiki_entry->gname.':'.$wiki_entry->pagename;
858                         if ($currentid == $wiki_entry->id) {
859                             $wikis['selected'] = $key;
860                         }
861                     }
862                 }
863             }
864         }
865         break;
866     }
867     
868     return $wikis;
871 function wiki_add_entry(&$wiki, &$course, $userid=0, $groupid=0) {
872 /// Adds a new wiki entry of the specified type, unless already entered.
873 /// No checking is done here. It is assumed that the caller has the correct
874 /// privileges to add this entry.
876     global $USER;
878     /// If this wiki already has a wiki_type entry, return false.
879     if (wiki_get_entry($wiki, $course, $userid, $groupid) !== false) {
880         return false;
881     }
883     $wiki_entry = new Object();
885     switch ($wiki->wtype) {
887     case 'student':
888         $wiki_entry->wikiid = $wiki->id;
889         $wiki_entry->userid = $userid ? $userid : $USER->id;
890         $wiki_entry->pagename = wiki_page_name($wiki);
891         $wiki_entry->timemodified = time();
892         break;
894     case 'group':
895         /// Get the groupmode. It's been added to the wiki object.
896         $groupmode = groups_get_activity_groupmode($wiki);
898         ///give the first groupid by default and try
899         $mygroups = mygroupid($course->id);
901         /// If there is a groupmode, get the group id.
902         if ($groupmode) {
903             $groupid = $groupid ? $groupid : $mygroups[0]/*mygroupid($course->id)*/;
904         }
905         /// If mode is 'nogroups', then groupid is zero.
906         else {
907             $groupid = 0;
908         }
909         $wiki_entry->wikiid = $wiki->id;
910         $wiki_entry->groupid = $groupid;
911         $wiki_entry->pagename = wiki_page_name($wiki);
912         $wiki_entry->timemodified = time();
914         break;
916     case 'teacher':
917         /// Get the groupmode. It's been added to the wiki object.
918         $groupmode = groups_get_activity_groupmode($wiki);
920         /// If there is a groupmode, get the user's group id.
921         if ($groupmode and $groupid == 0) {
922             $mygroupid = mygroupid($course->id);
923             $groupid = $mygroupid[0]/*mygroupid($course->id)*/;
924         }
926         $wiki_entry->wikiid = $wiki->id;
927         $wiki_entry->course = $wiki->course;
928         $wiki_entry->groupid = $groupid;
929         $wiki_entry->pagename = wiki_page_name($wiki);
930         $wiki_entry->timemodified = time();
931         break;
932     }
933     $wiki_entry->pagename = addslashes($wiki_entry->pagename);
935     return insert_record("wiki_entries", $wiki_entry, true);
938 function wiki_can_add_entry(&$wiki, &$user, &$course, $userid=0, $groupid=0) {
939 /// Returns true or false if the user can add a wiki entry for this wiki.
941     /// Get the groupmode. It's been added to the wiki object.
942     $groupmode = groups_get_activity_groupmode($wiki);
943     $mygroupid = mygroupid($course->id);
945     switch ($wiki->wtype) {
947     case 'student':
948 ///     A student can create their own wiki, if they are a member of that course.
949 ///     A user can create their own wiki at the site level.
950         if ($userid == 0) {
951             return (wiki_is_student($wiki, $user->id) or wiki_is_student($wiki, $user->id));
952         }
953 ///     An editing teacher can create any student wiki, or
954 ///     a non-editing teacher, if not assigned to a group can create any student wiki, or if assigned to a group can
955 ///     create any student wiki in their group.
956         else {
957             return ((($userid == $user->id) and wiki_is_student($wiki, $user->id)) or wiki_is_teacheredit($wiki) or
958                     (wiki_is_teacher($wiki) and (!$groupmode or $mygroupid == 0 or (groups_is_member($mygroupid, $userid)))));
959         }
960         break;
962     case 'group':
963         /// If mode is 'nogroups', then all participants can add wikis.
964         if (wiki_is_teacheredit($wiki, $user->id)) {
965             return true;
966         }
968         if (!$groupmode) {
969             return (wiki_is_student($wiki, $user->id) or wiki_is_teacher($wiki, $user->id));
970         }
971         /// If not requesting a group, must be a member of a group.
972         else if ($groupid == 0) {
973             return ($mygroupid != 0);
974         }
975         /// If requesting a group, must be an editing teacher, a non-editing teacher with no assigned group,
976         /// or a non-editing teacher requesting their group. or a student in group, but wiki is empty.
977         else {
978             return (wiki_is_teacheredit($wiki) or
979                    (wiki_is_teacher($wiki) and ($mygroupid == 0 or @in_array($groupid, $mygroupid))) or
980                    (wiki_is_student($wiki, $user->id) and @in_array($groupid, $mygroupid))
981                    );
982         }
983         break;
985     case 'teacher':
986         /// If mode is 'nogroups', then all teachers can add wikis.
987         if (!$groupmode) {
988             return wiki_is_teacher($wiki, $user->id);
989         }
990         /// If not requesting a group, must be a member of a group.
991         else if ($groupid == 0) {
992             return ($mygroupid != 0 and wiki_is_teacher($wiki));
993         }
994         /// If there is a group mode, non-editing teachers with an assigned group, can only create wikis
995         /// in their group. Non-editing teachers with no assigned group and editing teachers can create any wiki.
996         else {
997             return (wiki_is_teacheredit($wiki) or
998                     (wiki_is_teacher($wiki) and ($mygroupid == 0 or @in_array($groupid, $mygroupid))));
999         }
1000         break;
1001     }
1003     return false;
1006 function wiki_can_edit_entry(&$wiki_entry, &$wiki, &$user, &$course) {
1007 /// Returns true or false if the user can edit this wiki entry.
1009     $can_edit = false;
1010     $groupmode = groups_get_activity_groupmode($wiki);
1011     $mygroupid = mygroupid($course->id);
1013     /// Editing teacher's and admins can edit all wikis, non-editing teachers can edit wikis in their groups,
1014     /// or all wikis if group mode is 'no groups' or they don't belong to a group.
1015     if (wiki_is_teacheredit($wiki, $user->id) or
1016         ((!$groupmode or $mygroupid == 0) and wiki_is_teacher($wiki, $user->id))) {
1017         $can_edit = true;
1018     }
1019     else {
1020         switch ($wiki->wtype) {
1022         /// Only a teacher or the owner of a student wiki can edit it.
1023         case 'student':
1024             $can_edit = (($user->id == $wiki_entry->userid) or
1025                          ($groupmode and wiki_is_teacher($wiki, $user->id) and
1026                           groups_is_member($mygroupid, $wiki_entry->userid)));
1027             break;
1029         case 'group':
1030             /// If there is a groupmode, determine the user's group status.
1031             if ($groupmode) {
1032                 /// If the user is a member of the wiki group, they can edit the wiki.
1033                 $can_edit = groups_is_member($wiki_entry->groupid, $user->id);
1034             }
1035             /// If mode is 'nogroups', then all participants can edit the wiki.
1036             else {
1037                 $can_edit = (wiki_is_student($wiki, $user->id) or wiki_is_teacher($wiki, $user->id));
1038             }
1039             break;
1041         case 'teacher':
1042             /// If there is a groupmode, determine the user's group status.
1043             if ($groupmode) {
1044                 /// If the user is a member of the wiki group, they can edit the wiki.
1045                 $can_edit = (wiki_is_teacher($wiki, $user->id) and groups_is_member($wiki_entry->groupid, $user->id));
1046             }
1047             else {
1048                 $can_edit = wiki_is_teacher($wiki, $user->id);
1049             }
1050             break;
1051         }
1052     }
1053     return $can_edit;
1056 function wiki_user_can_access_student_wiki(&$wiki, $userid, &$course) {
1057     global $USER;
1059     /// Get the groupmode. It's been added to the wiki object.
1060     $groupmode = groups_get_activity_groupmode($wiki);
1061     $usersgroup = mygroupid($course->id);
1062     $isteacher = wiki_is_teacher($wiki, $USER->id);
1064     /// If this user is allowed to access this wiki then return TRUE.
1065     /// *** THIS COULD BE A PROBLEM, IF STUDENTS COULD EVER BE PART OF MORE THAN ONE GROUP ***
1066     /// A user can access a student wiki, if:
1067     ///     - it is their wiki,
1068     ///     - group mode is VISIBLEGROUPS,
1069     ///     - group mode is SEPARATEGROUPS, and the user is a member of the requested user's group,
1070     ///     - they are an editing teacher or administrator,
1071     ///     - they are a non-editing teacher not assigned to a specific group,
1072     ///     - they are a non-editing teacher and group mode is NOGROUPS.
1073     ///     - they are an administrator (mostly for site-level wikis).
1074     if (($userid and ($USER->id == $userid)) or ($groupmode == VISIBLEGROUPS) or
1075         (($groupmode == SEPARATEGROUPS) and groups_is_member($usersgroup, $userid)) or
1076         (wiki_is_teacheredit($wiki, $USER->id)) or
1077         (wiki_is_teacher($wiki, $USER->id) and (!$usersgroup or $groupmode == NOGROUPS))) {
1078         $can_access = true;
1079     }
1080     else {
1081         $can_access = false;
1082     }
1083     return $can_access;
1086 function wiki_user_can_access_group_wiki(&$wiki, $groupid, &$course) {
1087     global $USER;
1089     /// Get the groupmode. It's been added to the wiki object.
1090     $groupmode = groups_get_activity_groupmode($wiki);
1091     $usersgroup = mygroupid($course->id);
1092     $isteacher = wiki_is_teacher($wiki, $USER->id);
1094     /// A user can access a group wiki, if:
1095     ///     - group mode is NOGROUPS,
1096     ///     - group mode is VISIBLEGROUPS,
1097     ///     - group mode is SEPARATEGROUPS, and they are a member of the requested group,
1098     ///     - they are an editing teacher or administrator,
1099     ///     - they are a non-editing teacher not assigned to a specific group.
1100     if (($groupmode == NOGROUPS) or ($groupmode == VISIBLEGROUPS) or
1101         (($groupmode == SEPARATEGROUPS) and @in_array($groupid, $usersgroup)/*($usersgroup == $groupid)*/) or
1102         (wiki_is_teacheredit($wiki, $USER->id)) or
1103         (wiki_is_teacher($wiki, $USER->id) and !$usersgroup)) {
1104         $can_access = true;
1105     }
1106     else {
1107         $can_access = false;
1108     }
1109     return $can_access;
1112 function wiki_user_can_access_teacher_wiki(&$wiki, $groupid, &$course) {
1113     global $USER;
1115     /// Get the groupmode. It's been added to the wiki object.
1116     $groupmode = groups_get_activity_groupmode($wiki);
1118     /// A user can access a teacher wiki, if:
1119     ///     - group mode is NOGROUPS,
1120     ///     - group mode is VISIBLEGROUPS,
1121     ///     - group mode is SEPARATEGROUPS, and they are a member of the requested group,
1122     ///     - they are a teacher or administrator,
1123     if (($groupmode == NOGROUPS) or ($groupmode == VISIBLEGROUPS) or
1124         (($groupmode == SEPARATEGROUPS) and (@in_array($groupid, mygroupid($course->id))/*mygroupid($course->id) == $groupid*/)) or
1125         (wiki_is_teacher($wiki, $USER->id))){
1126         $can_access = true;
1127     }
1128     else {
1129         $can_access = false;
1130     }
1131     return $can_access;
1134 function wiki_get_owner(&$wiki_entry) {
1135     if ($wiki_entry->userid > 0) {
1136         $user = get_record('user', 'id', $wiki_entry->userid);
1137         $owner = fullname($user);
1138     }
1139     else if ($wiki_entry->groupid > 0) {
1140         $owner = groups_get_group_name($wiki_entry->groupid); //TODO:check.
1141     }
1142     else if ($wiki_entry->course > 0) {
1143         $course = get_record('course', 'id', $wiki_entry->course);
1144         $owner = $course->shortname;
1145     }
1146     else {
1147         $owner = '- '.get_string("ownerunknown","wiki").' -';
1148     }
1149     return $owner;
1152 function wiki_print_search_form($cmid, $search="", $userid, $groupid, $return=false) {
1153     global $CFG;
1154     # TODO: Add Group and User !!!
1155     $output = "<form id=\"search\" action=\"$CFG->wwwroot/mod/wiki/view.php\">";
1156     $output .="<fieldset class='invisiblefieldset'>";
1157     $output .= "<span style='font-size:0.6em;'>";
1158     $output .= "<input value=\"".get_string("searchwiki", "wiki").":\" type=\"submit\" />";
1159     $output .= "<input name=\"id\" type=\"hidden\" value=\"$cmid\" />";
1160     $output = $output.($groupid?"<input name=\"groupid\" type=\"hidden\" value=\"$groupid\" />":"");
1161     $output = $output.($userid?"<input name=\"userid\" type=\"hidden\" value=\"$userid\" />":"");
1162     $output .= "<input name=\"q\" type=\"text\" size=\"20\" value=\"".s($search)."\" />".' ';
1163     $output .= "</span>";
1164     $output .= "<input name=\"page\" type=\"hidden\" value=\"SearchPages\" />";
1165     $output .= "</fieldset>";
1166     $output .= "</form>";
1168     if ($return) {
1169         return $output;
1170     }
1171     echo $output;
1174 function wiki_print_wikilinks_block($cmid, $binary=false, $return=false) {
1175 /// Prints a link-list of special wiki-pages
1176    global $CFG, $ewiki_title;
1178    $links=array();
1180    $links["SiteMap"]=get_string("sitemap", "wiki");
1181    $links["PageIndex"]=get_string("pageindex", "wiki");
1182    $links["NewestPages"]=get_string("newestpages", "wiki");
1183    $links["MostVisitedPages"]=get_string("mostvisitedpages", "wiki");
1184    $links["MostOftenChangedPages"]=get_string("mostoftenchangedpages", "wiki");
1185    $links["UpdatedPages"]=get_string("updatedpages", "wiki");
1186    $links["OrphanedPages"]=get_string("orphanedpages", "wiki");
1187    $links["WantedPages"]=get_string("wantedpages", "wiki");
1188    $links["WikiExport"]=get_string("wikiexport", "wiki");
1189    if($binary) {
1190      $links["FileDownload"]=get_string("filedownload", "wiki");
1191    }
1192    popup_form(EWIKI_SCRIPT, $links, "wikilinks", "", get_string("choosewikilinks", "wiki"), "", "", $return);
1195 function wiki_print_page_actions($cmid, $specialpages, $page, $action, $binary=false, $canedit=true) {
1196 /// Displays actions which can be performed on the page
1198   $page=array();
1200   // Edit this Page
1201   if (in_array($action, array("edit", "links", "info", "attachments"))) {
1202     $page["view/$page"]=get_string("viewpage","wiki");
1203   }
1204   if ($canedit && !in_array($page, $specialpages) && $action != "edit") {
1205     $page["edit/$page"]=get_string("editthispage","wiki");
1206   }
1207   if ($action != "links") {
1208     $page["links/$page"]=get_string("backlinks","wiki");
1209   }
1210   if ($canedit && !in_array($page, $specialpages) && $action!="info") {
1211     $page["info/$page"]=get_string("pageinfo","wiki");
1212   }
1213   if($canedit && $binary && !in_array($page, $specialpages) && $action != "attachments") {
1214     $page["attachments/$page"]=get_string("attachments","wiki");
1215   }
1217   popup_form(EWIKI_SCRIPT, $page, "wikiactions", "", get_string("action", "wiki"), "", "", false);
1220 function wiki_print_administration_actions($wiki, $cmid, $userid, $groupid, $page, $noeditor, $course) {
1221 /// Displays actions which can be performed on the page
1223   /// Create the URL
1224   $ewscript = 'admin.php?id='.$cmid;
1225   if (isset($userid) && $userid!=0) $ewscript .= '&amp;userid='.$userid;
1226   if (isset($groupid) && $groupid!=0) $ewscript .= '&amp;groupid='.$groupid;
1227   if (isset($page)) $ewscript .= '&amp;page='.$page;
1228   $ewscript.="&amp;action=";
1231     /// Build that action array according to wiki flags.
1232     $action = array();
1233     $isteacher = wiki_is_teacher($wiki);
1235     if ($wiki->setpageflags or $isteacher) {
1236         $action['setpageflags'] = get_string('setpageflags', 'wiki');
1237     }
1238     if ($wiki->removepages or $isteacher) {
1239         $action['removepages']  = get_string('removepages', 'wiki');
1240     }
1241     if ($wiki->strippages or $isteacher) {
1242         $action['strippages']  = get_string('strippages', 'wiki');
1243     }
1244     if ($wiki->revertchanges or $isteacher) {
1245         $action['revertpages'] = get_string('revertpages', 'wiki');
1246     }
1248   if($noeditor) {
1249     $action["checklinks"]=get_string("checklinks", "wiki");
1250   }
1251   popup_form($ewscript, $action, "wikiadministration", "", get_string("chooseadministration", "wiki"), "", "", false);
1254 function wiki_admin_get_flagarray() {
1255   $ret = array(
1256      EWIKI_DB_F_TEXT => get_string("flagtxt","wiki"),
1257      EWIKI_DB_F_BINARY => get_string("flagbin","wiki"),
1258      EWIKI_DB_F_DISABLED => get_string("flagoff","wiki"),
1259      EWIKI_DB_F_HTML => get_string("flaghtm","wiki"),
1260      EWIKI_DB_F_READONLY => get_string("flagro","wiki"),
1261      EWIKI_DB_F_WRITEABLE => get_string("flagwr","wiki"),
1262   );
1264   return $ret;
1267 ///////// Ewiki Administration. Mostly taken from the ewiki/tools folder and changed
1268 function wiki_admin_setpageflags_list($pageflagstatus) {
1269   $FD = wiki_admin_get_flagarray();
1270   $table = new Object();
1271   $table->head = array(get_string("pagename","wiki"), get_string("flags","wiki"));
1272   if($pageflagstatus) {
1273     $table->head[]=get_string("status","wiki");
1274   }
1276   $result = ewiki_database("GETALL", array("version", "flags"));
1277   while ($row = $result->get()) {
1278     $id = $row["id"];
1279     $data = ewiki_database("GET", $row);
1281     $cell_pagename="";
1282     $cell_flags="";
1283     if ($data["flags"] & EWIKI_DB_F_TEXT) {
1284         $cell_pagename .= '<a href="' . EWIKI_SCRIPT . $id . '">';
1285     } else {
1286         $cell_pagename .= '<a href="' . EWIKI_SCRIPT_BINARY . $id . '">';
1287     }
1288     $cell_pagename .= s($id) . '</a> / '.get_string("version","wiki").": ".$row["version"];
1290     foreach ($FD as $n=>$str) {
1291         $cell_flags .='<input type="checkbox" name="flags['. rawurlencode($id)
1292             . '][' . $n . ']" value="1" '
1293             . (($data["flags"] & $n) ? "checked=\"checked\"" : "")
1294             . ' />'.$str. ' ';
1295     }
1296     if($pageflagstatus) {
1297       $table->data[]=array($cell_pagename, $cell_flags, $pageflagstatus[$id]);
1298     } else {
1299       $table->data[]=array($cell_pagename, $cell_flags);
1300     }
1301   }
1302   return $table;
1305 function wiki_admin_setpageflags($pageflags) {
1306   $FD = wiki_admin_get_flagarray();
1308   $status=array();
1309   if($pageflags) {
1310      foreach($pageflags as $page=>$fa) {
1312         $page = rawurldecode($page);
1314         $flags = 0;
1315         $fstr = "";
1316         foreach($fa as $num=>$isset) {
1317            if ($isset) {
1318               $flags += $num;
1319               $fstr .= ($fstr?",":""). $FD[$num];
1320            }
1321         }
1323         #$status[$page] .= "{$flags}=[{$fstr}]";
1325         $data = ewiki_database("GET", array("id" => $page));
1327         if ($data["flags"] != $flags) {
1328            $data["flags"] = $flags;
1329            $data["author"] = "ewiki-tools, " . ewiki_author();
1330            $data["version"]++;
1331            ewiki_database("WRITE", $data);
1332            $status[$page] =  "<b>".get_string("flagsset","wiki")."</b> ".$status[$page];
1333         }
1334      }
1335   }
1336   return $status;
1340 function wiki_admin_remove_list($listall="") {
1341   /// Table header
1342   $table = new Object();
1343   $table->head = array("&nbsp;", get_string("pagename","wiki"), get_string("errororreason","wiki"));
1345   /// Get all pages
1346   $result = ewiki_database("GETALL", array("version"));
1347   $selected = array();
1349   /// User wants to see all pages
1350   if ($listall) {
1351     while ($row = $result->get()) {
1352       $selected[$row["id"]] = get_string("listall","wiki")."<br />";
1353     }
1354   }
1355   while ($page = $result->get()) {
1356     $id = $page["id"];
1357     $page = ewiki_database("GET", array("id"=>$id));
1358     $flags = $page["flags"];
1359     #print "$id ".strlen(trim(($page["content"])))."<br />";
1361     if (!strlen(trim(($page["content"]))) && !($flags & EWIKI_DB_F_BINARY)) {
1362         @$selected[$id] .= get_string("emptypage","wiki")."<br />";
1363     }
1365     // Check for orphaned pages
1366     $result2 = ewiki_database("SEARCH", array("content" => $id));
1367     $orphanedpage=true;
1368     if ($result2 && $result2->count()) {
1369         while ($row = $result2->get()) {
1370           $checkcontent = ewiki_database("GET", array("id"=>$row["id"]));
1371           $checkcontent = strtolower($checkcontent["content"]);
1373           if(strpos($checkcontent, strtolower($id)) !== false) {
1374             $orphanedpage=false;
1375           }
1377           #echo "rc({$row['id']})==>($id): $check2 <br />";
1378         }
1379     }
1381     /// Some more reasons for Deletion...
1382     if ($orphanedpage && $id!=EWIKI_PAGE_INDEX &&!($flags & EWIKI_DB_F_BINARY)) {
1383         @$selected[$id] .= get_string("orphanedpage","wiki")."<br />";
1384     }
1386     if ($flags & EWIKI_DB_F_DISABLED) {
1387         @$selected[$id] .= get_string("disabledpage","wiki")."<br />";
1388     }
1390     if (($flags & 3) == 3) {
1391         @$selected[$id] .= get_string("errorbinandtxt","wiki")."<br />";
1392     }
1394     if (!($flags & 3)) {
1395         @$selected[$id] .= get_string("errornotype","wiki")."<br />";
1396     }
1398     if ($flags & EWIKI_DB_F_HTML) {
1399         @$selected[$id] .= get_string("errorhtml","wiki")."<br />";
1400     }
1402     if (($flags & EWIKI_DB_F_READONLY) && !($flags & EWIKI_DB_F_BINARY)) {
1403         @$selected[$id] .= get_string("readonly","wiki")."<br />";
1404     }
1406     if (($flags & EWIKI_DB_F_READONLY) && ($flags & EWIKI_DB_F_WRITEABLE)) {
1407         @$selected[$id] .= get_string("errorroandwr","wiki")."<br />";
1408     }
1410     if (strlen($page["content"]) >= 65536) {
1411         @$selected[$id] .= get_string("errorsize","wiki")."<br />";
1412     }
1414     if (strpos($page["refs"], "\n".get_string("deletemewikiword","wiki")."\n")!==false) {
1415         @$selected[$id] .= get_string("deletemewikiwordfound","wiki",get_string("deletemewikiword","wiki"))."<br />";
1416     }
1417   }
1419   foreach ($selected as $id => $reason) {
1420     $table_checkbox='<input type="checkbox" value="'.rawurlencode($id).'" name="pagestodelete[]" />';
1422     #-- link & id
1423     if (strpos($id, EWIKI_IDF_INTERNAL) === false) {
1424         $table_page='<a href="' . ewiki_script("", $id) . '">';
1425     } else {
1426         $table_page='<a href="' . ewiki_script_binary("", $id) . '">';
1427     }
1428     $table_page .= s($id) . '</a>';
1430     #-- print reason
1431     $table_reason=$reason;
1433     $table->data[]=array($table_checkbox, $table_page, $table_reason);
1434   }
1436   return $table;
1439 /// This function actually removes the pages
1440 function wiki_admin_remove($pagestodelete, $course, $wiki, $userid, $groupid) {
1441   $ret="";
1442   foreach ($pagestodelete as $id) {
1444     $id = rawurldecode($id);
1446     $data = ewiki_database("GET", array("id"=>$id));
1447     for ($version=1; $version<=$data["version"]; $version++) {
1448         ewiki_database("DELETE", array("id"=>$id, "version"=>$version));
1449         if($data["flags"] & EWIKI_DB_F_BINARY) {
1450           $filepath=moodle_binary_get_path($id, $data["meta"], $course, $wiki, $userid, $groupid);
1451           @unlink("$filepath");
1452         }
1453     }
1455   }
1456   return $ret;
1459 function wiki_admin_strip_list($pagestostrip="",$version="",$err="") {
1460   /// Table header
1461   $table = new Object();
1462   $table->head = array("&nbsp;", get_string("pagename","wiki"), get_string("deleteversions","wiki"));
1464   $vc=ewiki_database("COUNTVERSIONS", array());
1465   $result = ewiki_database("GETALL",array());
1466   $i=0;
1467   while ($row = $result->get()) {
1468      $id = $row["id"];
1469      if($vc[$id]>1) {
1470         $error="";
1471         if($err[$id]) {
1472           $error=" ".join(", ",$err[$id]);
1473         }
1474         $checked="";
1475         if($pagestostrip=="" || $pagestostrip[$i]) {
1476           $checked=" checked=\"checked\"";
1477         }
1478         if($version=="") {
1479           $versiondefault="1-".($row["version"]-1);
1480         } else {
1481           $versiondefault=$version[$i];
1482         }
1483         $table->data[]=array('<input type="checkbox" value="'.rawurlencode($id).'" name="pagestostrip['.$i.']" '.$checked.' />',
1484                         '<A HREF="'.EWIKI_SCRIPT.$id.'">'.s($id).'</A> / '.get_string("version","wiki").": ".$row["version"],
1485                         '<input name="version['.$i.']" value="'.$versiondefault.'" size="7" />'.$error);
1487       }
1488       $i++;
1489   }
1490   return $table;
1493 function wiki_admin_strip_versions($pagestostrip, $version, &$err) {
1494   $ret=array();
1495   foreach ($pagestostrip as $key => $id_ue) {
1497     $id = rawurldecode($id_ue);
1498     if (preg_match('/^(\d+)[-\s._:]+(\d+)$/', trim($version[$key]), $uu)) {
1499       $versA = $uu[1];
1500       $versZ = $uu[2];
1502       // Let the last Version in the database
1503       $checkdata = ewiki_database("GET", array("id" => $id));
1504       if($versZ>=$checkdata["version"]) {
1505             $err[$id][] = get_string("versionrangetoobig","wiki");
1506       } else {
1507         if($versA<=$versZ) {
1508           for ($v=$versA; $v<=$versZ; $v++) {
1509               $ret[$id][]=$v;
1510           }
1511         } else {
1512           $err[$id][]=get_string("wrongversionrange","wiki",$version[$key]);
1513         }
1514       }
1515     }
1516     else {
1517       $err[$id][]=get_string("wrongversionrange","wiki",$version[$key]);
1518     }
1519   }
1520   return $ret;
1523 function wiki_admin_strip($pagestostrip) {
1524   /// Purges old page-versions
1525   foreach($pagestostrip as $id => $versions) {
1526     foreach($versions as $version) {
1527       ewiki_database("DELETE", array("id"=>$id, "version"=>$version));
1528     }
1529   }
1532 function wiki_admin_checklinks_list() {
1533   $ret=array();
1534   $result = ewiki_database("GETALL",array());
1535   while ($row = $result->get()) {
1536     if(!($row["flags"] & EWIKI_DB_F_BINARY)) {
1537       $index=s($row["id"]);
1538       $ret[$index] = $row["id"];
1539     }
1540   }
1541   return $ret;
1544 function wiki_admin_checklinks($pagetocheck) {
1545   /// Checks http:// Links
1546   $ret="";
1547   if($pagetocheck) {
1548      $get = ewiki_database("GET", array("id" => $pagetocheck));
1549      $content = $get["content"];
1551      preg_match_all('_(http.?://[^\s"\'<>#,;]+[^\s"\'<>#,;.])_', $content, $links);
1552      $badlinks = array();
1553      if(!$links[1]) {
1554        $ret = get_string("nolinksfound","wiki")."<br /><br />";
1555      } else {
1556        foreach ($links[1] as $href) {
1557           #print "[ $href ]";
1558           #$d = @implode("", @file($href));
1559           $d="";
1560           if($checkfd = @fopen($href, 'r')) {
1561             fclose($checkfd);
1562             $d="OK";
1563           }
1564           if (empty($d) || !strlen(trim($d)) || stristr("not found", $d) || stristr("error 404", $d)) {
1565              $ret.="[".get_string("linkdead","wiki")."] $href <br />\n";
1566              $badlinks[] = $href;
1567           } else {
1568              $ret.="[".get_string("linkok","wiki")."] $href <br />\n";
1569           }
1570        }
1571      }
1573      /// Remove old Notices
1574      $content = eregi_replace(' µµ__~\['.get_string("offline","wiki").'\]__µµ ','', $content);
1576      #-- replace dead links
1577      foreach ($badlinks as $href) {
1578         $content = preg_replace("\377^(.*)($href)\377m", '$1 µµ__~['.get_string("offline","wiki").']__µµ $2', $content);
1579      }
1581      #-- compare against db content
1582      if ($content != $get["content"]) {
1583         $get["content"] = $content;
1584         $get["version"]++;
1585         $get["author"] = ewiki_author("ewiki_checklinks");
1586         $get["lastmodified"] = time();
1588         ewiki_database("WRITE", $get);
1589      }
1590   }
1591   return $ret;
1594 function wiki_admin_revert($proceed, $authorfieldpattern, $changesfield, $howtooperate, $deleteversions) {
1595   $ret="";
1596   #-- params
1597   $m_time = $changesfield * 3600;
1598   $depth = $deleteversions - 1;
1599   $depth = ($depth>0?$depth:0);
1601   #-- walk through
1602   $result = ewiki_database("GETALL", array("id", "author", "lastmodified"));
1603   while ($row = $result->get()) {
1604     $id = $row["id"];
1605     #-- which versions to check
1606     $verZ = $row["version"];
1607     if ($howtooperate=="lastonly") {
1608       $verA = $verZ;
1609     }
1610     else {
1611       $verA = $verZ-$depth;
1612       if ($verA <= 0) {
1613           $verA = 1;
1614       }
1615     }
1617     for ($ver=$verA; $ver<=$verZ; $ver++) {
1618       #-- load current $ver database entry
1619       if ($verA != $verZ) {
1620           $row = ewiki_database("GET", array("id"=>$id, "version"=>$ver));
1621       }
1623       #-- match
1624       if (stristr($row["author"], $authorfieldpattern) && ($row["lastmodified"] + $m_time > time())) {
1625         $ret .= "$id (".get_string("versionstodelete","wiki").": ";
1626         #-- delete multiple versions
1627         if ($howtooperate=="allsince") {
1628           while ($ver<=$verZ) {
1629               $ret .= " $ver";
1630               if ($proceed) {
1631                 ewiki_database("DELETE", array("id"=>$id, "version"=>$ver));
1632               }
1633               $ver++;
1634           }
1635         }
1636         #-- or just the affected one
1637         else {
1638           $ret .= " $ver";
1639           if ($proceed) {
1640             ewiki_database("DELETE", $row);
1641           }
1642         }
1643         $ret .= ")<br />";
1644         break;
1645       }
1646     } #-- for($ver)
1647   } #-- while($row)
1648   return $ret;
1652 function wiki_get_view_actions() {
1653     return array('view','view all');
1656 function wiki_get_post_actions() {
1657     return array('hack');
1661 /**
1662  * Obtains an editing lock on a wiki page.
1663  * @param int $wikiid ID of wiki object.
1664  * @param string $pagename Name of page.
1665  * @return array Two-element array with a boolean true (if lock has been obtained)
1666  *   or false (if lock was held by somebody else). If lock was held by someone else,
1667  *   the values of the wiki_locks entry are held in the second element; if lock was
1668  *   held by current user then the the second element has a member ->id only.
1669  */
1670 function wiki_obtain_lock($wikiid,$pagename) {
1671     global $USER;
1673     // Check for lock
1674     $alreadyownlock=false;
1675     if($lock=get_record('wiki_locks','pagename',$pagename,'wikiid', $wikiid)) {
1676         // Consider the page locked if the lock has been confirmed within WIKI_LOCK_PERSISTENCE seconds
1677         if($lock->lockedby==$USER->id) {
1678             // Cool, it's our lock, do nothing except remember it in session
1679             $lockid=$lock->id;
1680             $alreadyownlock=true;
1681         } else if(time()-$lock->lockedseen < WIKI_LOCK_PERSISTENCE) {
1682             return array(false,$lock);
1683         } else {
1684             // Not locked any more. Get rid of the old lock record.
1685             if(!delete_records('wiki_locks','pagename',$pagename,'wikiid', $wikiid)) {
1686                 print_error('Unable to delete lock record');
1687             }
1688         }
1689     }
1691     // Add lock
1692     if(!$alreadyownlock) {
1693         // Lock page
1694         $newlock=new stdClass;
1695         $newlock->lockedby=$USER->id;
1696         $newlock->lockedsince=time();
1697         $newlock->lockedseen=$newlock->lockedsince;
1698         $newlock->wikiid=$wikiid;
1699         $newlock->pagename=$pagename;
1700         if(!$lockid=insert_record('wiki_locks',$newlock)) {
1701             print_error('Unable to insert lock record');
1702         }
1703     }
1705     // Store lock information in session so we can clear it later
1706     if(!array_key_exists(SESSION_WIKI_LOCKS,$_SESSION)) {
1707         $_SESSION[SESSION_WIKI_LOCKS]=array();
1708     }
1709     $_SESSION[SESSION_WIKI_LOCKS][$wikiid.'_'.$pagename]=$lockid;
1710     $lockdata=new StdClass;
1711     $lockdata->id=$lockid;
1712     return array(true,$lockdata);
1715 /**
1716  * If the user has an editing lock, releases it. Has no effect otherwise.
1717  * Note that it doesn't matter if this isn't called (as happens if their
1718  * browser crashes or something) since locks time out anyway. This is just
1719  * to avoid confusion of the 'what? it says I'm editing that page but I'm
1720  * not, I just saved it!' variety.
1721  * @param int $wikiid ID of wiki object.
1722  * @param string $pagename Name of page.
1723  */
1724 function wiki_release_lock($wikiid,$pagename) {
1725     if(!array_key_exists(SESSION_WIKI_LOCKS,$_SESSION)) {
1726         // No locks at all in session
1727         return;
1728     }
1730     $key=$wikiid.'_'.$pagename;
1732     if(array_key_exists($key,$_SESSION[SESSION_WIKI_LOCKS])) {
1733         $lockid=$_SESSION[SESSION_WIKI_LOCKS][$key];
1734         unset($_SESSION[SESSION_WIKI_LOCKS][$key]);
1735         if(!delete_records('wiki_locks','id',$lockid)) {
1736             print_error("Unable to delete lock record.");
1737         }
1738     }
1742 ?>