Fix a possible race condition in the PaintWeb DML code.
[moodle/mihaisucan.git] / mod / wiki / lib.php
blob4b340637e75926ea5d9092abd7f34098eba94be5
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 *****
25 ********************************************/
26 function wiki_context($wiki) {
27 //TODO: add some $cm caching if needed
28 if (is_object($wiki)) {
29 $wiki = $wiki->id;
31 if (! $cm = get_coursemodule_from_instance('wiki', $wiki)) {
32 error('Course Module ID was incorrect');
35 return get_context_instance(CONTEXT_MODULE, $cm->id);
38 function wiki_is_teacher($wiki, $userid=NULL) {
39 return has_capability('mod/wiki:manage', wiki_context($wiki), $userid);
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);
47 function wiki_is_student($wiki, $userid=NULL) {
48 return has_capability('mod/wiki:participate', wiki_context($wiki), $userid);
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);
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.html) 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);
75 function wiki_update_instance($wiki) {
76 /// Given an object containing all the necessary data,
77 /// (defined by the form in mod.html) 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);
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
97 closedir($handle);
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;
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!");
126 #if (!$exception) { // Delete directory as well, if empty
127 wiki_rmdir("$basedir");
132 # Delete any dependent records here #
133 if(!delete_records("wiki_locks","wikiid",$wiki->id)) {
134 $result = false;
137 if (! delete_records("wiki", "id", $wiki->id)) {
138 $result = false;
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;
147 if (! delete_records("wiki_entries", "id", "$wiki_entry->id")) {
148 $result = false;
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;
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";
187 if (!$logs = get_records_sql($sql)){
188 return false;
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;
200 /// Process log->url and rebuild it here to properly clean the pagename - MDL-15896
201 $extractedpage = preg_replace('/^.*&page=/', '', $log->url);
202 $log->url = preg_replace('/page=.*$/', 'page='.urlencode($extractedpage), $log->url);
204 $wikis[$log->info] = wiki_log_info($log);
205 $wikis[$log->info]->pagename = $log->info;
206 $wikis[$log->info]->time = $log->time;
207 $wikis[$log->info]->url = str_replace('&', '&amp;', $log->url);
210 if (!$wikis) {
211 return false;
213 print_headline(get_string('updatedwikipages', 'wiki').':', 3);
214 foreach ($wikis as $wiki) {
215 print_recent_activity_note($wiki->time, $wiki, $wiki->pagename,
216 $CFG->wwwroot.'/mod/wiki/'.$wiki->url);
219 return false;
222 function wiki_log_info($log) {
223 global $CFG;
224 return get_record_sql("SELECT u.firstname, u.lastname
225 FROM {$CFG->prefix}user u
226 WHERE u.id = '$log->userid'");
229 function wiki_cron () {
230 /// Function to be run periodically according to the moodle cron
231 /// This function searches for things that need to be done, such
232 /// as sending out mail, toggling flags etc ...
234 // Delete expired locks
235 $result=delete_records_select('wiki_locks','lockedseen < '.(time()-WIKI_LOCK_PERSISTENCE));
237 return $result;
240 function wiki_get_participants($wikiid) {
241 //Returns the users with data in one wiki
242 //(users with records in wiki_pages and wiki_entries)
244 global $CFG;
246 //Get users from wiki_pages
247 $st_pages = get_records_sql("SELECT DISTINCT u.id, u.id
248 FROM {$CFG->prefix}user u,
249 {$CFG->prefix}wiki_entries e,
250 {$CFG->prefix}wiki_pages p
251 WHERE e.wikiid = '$wikiid' and
252 p.wiki = e.id and
253 u.id = p.userid");
255 //Get users from wiki_entries
256 $st_entries = get_records_sql("SELECT DISTINCT u.id, u.id
257 FROM {$CFG->prefix}user u,
258 {$CFG->prefix}wiki_entries e
259 WHERE e.wikiid = '$wikiid' and
260 u.id = e.userid");
262 //Add entries to pages
263 if ($st_entries) {
264 foreach ($st_entries as $st_entry) {
265 $st_pages[$st_entry->id] = $st_entry;
269 return $st_pages;
273 //////////////////////////////////////////////////////////////////////////////////////
274 /// Any other wiki functions go here. Each of them must have a name that
275 /// starts with wiki_
277 function wiki_wiki_name($wikiname) {
278 /// Return the passed in string in Wiki name format.
279 /// Remove any leading and trailing whitespace, capitalize all the words
280 /// and then remove any internal whitespace.
282 if (wiki_is_wiki_name($wikiname)) {
283 return $wikiname;
285 else {
286 /// Create uppercase words and remove whitespace.
287 $wikiname = preg_replace("/(\w+)\s/", "$1", ucwords(trim($wikiname)));
289 /// Check again - there may only be one word.
290 if (wiki_is_wiki_name($wikiname)) {
291 return $wikiname;
293 /// If there is only one word, append default wiki name to it.
294 else {
295 return $wikiname.get_string('wikidefaultpagename', 'wiki');
300 function wiki_is_wiki_name($wikiname) {
301 /// Check for correct wikiname syntax and return true or false.
303 /// If there are spaces between the words, incorrect format.
304 if (preg_match_all('/\w+/', $wikiname, $out) > 1) {
305 return false;
307 /// If there isn't more than one group of uppercase letters separated by
308 /// lowercase letters or '_', incorrect format.
309 else if (preg_match_all('/[A-Z]+[a-z_]+/', $wikiname, $out) > 1) {
310 return true;
312 else {
313 return false;
317 function wiki_page_name(&$wiki) {
318 /// Determines the wiki's page name and returns it.
319 if (!empty($wiki->initialcontent)) {
320 $ppos = strrpos($wiki->initialcontent, '/');
321 if ($ppos === false) {
322 $pagename = $wiki->initialcontent;
324 else {
325 $pagename = substr($wiki->initialcontent, $ppos+1);
328 else if (!empty($wiki->pagename)) {
329 $pagename = $wiki->pagename;
331 else {
332 $pagename = $wiki->name;
334 return $pagename;
337 function wiki_content_dir(&$wiki) {
338 /// Determines the wiki's default content directory (if there is one).
339 global $CFG;
341 if (!empty($wiki->initialcontent)) {
342 $ppos = strrpos($wiki->initialcontent, '/');
343 if ($ppos === false) {
344 $subdir = '';
346 else {
347 $subdir = substr($wiki->initialcontent, 0, $ppos+1);
349 $contentdir = $CFG->dataroot.'/'.$wiki->course.'/'.$subdir;
351 else {
352 $contentdir = false;
354 return $contentdir;
357 function wiki_get_course_wikis($courseid, $wtype='*') {
358 /// Returns all wikis for the specified course and optionally of the specified type.
360 $select = 'course = '.$courseid;
361 if ($wtype != '*') {
362 $select .= ' AND wtype = \''.$wtype.'\'';
364 return get_records_select('wiki', $select, 'id');
367 function wiki_has_entries(&$wiki) {
368 /// Returns true if wiki already has wiki entries; otherwise false.
370 return record_exists('wiki_entries', 'wikiid', $wiki->id);
373 function wiki_get_entries(&$wiki, $byindex=NULL) {
374 /// Returns an array with all wiki entries indexed by entry id; false if there are none.
375 /// If the optional $byindex is specified, returns the entries indexed by that field.
376 /// Valid values for $byindex are 'student', 'group'.
377 global $CFG;
379 if ($byindex == 'student') {
380 return get_records('wiki_entries', 'wikiid', $wiki->id, '',
381 'userid,id,wikiid,course,groupid,pagename,timemodified');
383 else if ($byindex == 'group') {
384 return get_records('wiki_entries', 'wikiid', $wiki->id, '',
385 'groupid,id,wikiid,course,userid,pagename,timemodified');
387 else {
388 return get_records('wiki_entries', 'wikiid', $wiki->id);
392 function wiki_get_default_entry(&$wiki, &$course, $userid=0, $groupid=0) {
393 /// Returns the wiki entry according to the wiki type.
394 /// Optionally, will return wiki entry for $userid student wiki, or
395 /// $groupid group or teacher wiki.
396 /// Creates one if it needs to and it can.
397 global $USER;
398 /// If there is a groupmode, get the user's group id.
399 $groupmode = groups_get_activity_groupmode($wiki);
400 // if groups mode is in use and no group supplied, use the first one found
401 if ($groupmode && !$groupid) {
402 if(($mygroupids=mygroupid($course->id)) && count($mygroupids)>0) {
403 // Use first group. They ought to be able to change later
404 $groupid=$mygroupids[0];
405 } else {
406 // Whatever groups are in the course, pick one
407 $coursegroups = groups_get_all_groups($course->id);
408 if(!$coursegroups || count($coursegroups)==0) {
409 error("Can't access wiki in group mode when no groups are configured for the course");
411 $unkeyed=array_values($coursegroups); // Make sure first item is index 0
412 $groupid=$unkeyed[0]->id;
416 /// If the wiki entry doesn't exist, can this user create it?
417 if (($wiki_entry = wiki_get_entry($wiki, $course, $userid, $groupid)) === false) {
418 if (wiki_can_add_entry($wiki, $USER, $course, $userid, $groupid)) {
419 wiki_add_entry($wiki, $course, $userid, $groupid);
420 if (($wiki_entry = wiki_get_entry($wiki, $course, $userid, $groupid)) === false) {
421 error("Could not add wiki entry.");
425 //print_object($wiki_entry);
426 return $wiki_entry;
429 function wiki_get_entry(&$wiki, &$course, $userid=0, $groupid=0) {
430 /// Returns the wiki entry according to the wiki type.
431 /// Optionally, will return wiki entry for $userid student wiki, or
432 /// $groupid group or teacher wiki.
433 global $USER;
435 switch ($wiki->wtype) {
436 case 'student':
437 /// If a specific user was requested, return it, if allowed.
438 if ($userid and wiki_user_can_access_student_wiki($wiki, $userid, $course)) {
439 $wentry = wiki_get_student_entry($wiki, $userid);
442 /// If there is no entry for this user, check if this user is a teacher.
443 else if (!$wentry = wiki_get_student_entry($wiki, $USER->id)) {
444 /* if (wiki_is_teacher($wiki, $USER->id)) {
445 /// If this user is a teacher, return the first entry.
446 if ($wentries = wiki_get_entries($wiki)) {
447 $wentry = current($wentries);
451 break;
453 case 'group':
454 /// If there is a groupmode, get the user's group id.
455 $groupmode = groups_get_activity_groupmode($wiki);
456 if($groupmode) {
457 if(!$groupid) {
458 if(($mygroupids=mygroupid($course->id)) && count($mygroupids)>0) {
459 // Use first group. They ought to be able to change later
460 $groupid=$mygroupids[0];
461 } else {
462 // Whatever groups are in the course, pick one
463 $coursegroups = groups_get_all_groups($course->id);
464 if(!$coursegroups || count($coursegroups)==0) {
465 error("Can't access wiki in group mode when no groups are configured for the course");
467 $unkeyed=array_values($coursegroups); // Make sure first item is index 0
468 $groupid=$unkeyed[0]->id;
472 //echo "groupid is in wiki_get_entry ".$groupid."<br />";
473 /// If a specific group was requested, return it, if allowed.
474 if ($groupid and wiki_user_can_access_group_wiki($wiki, $groupid, $course)) {
475 $wentry = wiki_get_group_entry($wiki, $groupid);
476 } else {
477 error("Cannot access any groups for this wiki");
480 /// If mode is 'nogroups', then groupid is zero.
481 else {
482 $wentry = wiki_get_group_entry($wiki, 0);
484 break;
486 case 'teacher':
487 /// If there is a groupmode, get the user's group id.
488 if (groupmode($course, $wiki)) {
489 $mygroupids = mygroupid($course->id);//same here, default to the first one
490 $groupid = $groupid ? $groupid : $mygroupids[0]/*mygroupid($course->id)*/;
493 /// If a specific group was requested, return it, if allowed.
494 if (wiki_user_can_access_teacher_wiki($wiki, $groupid, $course)) {
495 $wentry = wiki_get_teacher_entry($wiki, $groupid);
497 break;
499 return $wentry;
502 function wiki_get_teacher_entry(&$wiki, $groupid=0) {
503 /// Returns the wiki entry for the wiki teacher type.
504 return get_record('wiki_entries', 'wikiid', $wiki->id, 'course', $wiki->course, 'groupid', $groupid);
507 function wiki_get_group_entry(&$wiki, $groupid=null) {
508 /// Returns the wiki entry for the given group.
509 return get_record('wiki_entries', 'wikiid', $wiki->id, 'groupid', $groupid);
512 function wiki_get_student_entry(&$wiki, $userid=null) {
513 /// Returns the wiki entry for the given student.
514 global $USER;
516 if (is_null($userid)) {
517 $userid = $USER->id;
519 return get_record('wiki_entries', 'wikiid', $wiki->id, 'userid', $userid);
522 function wiki_get_other_wikis(&$wiki, &$user, &$course, $currentid=0) {
523 /// Returns a list of other wikis to display, depending on the type, group and user.
524 /// Returns the key containing the currently selected entry as well.
526 global $CFG, $id;
528 $wikis = false;
530 $groupmode = groups_get_activity_groupmode($wiki);
531 $mygroupid = mygroupid($course->id);
532 $isteacher = wiki_is_teacher($wiki, $user->id);
533 $isteacheredit = wiki_is_teacheredit($wiki, $user->id);
535 $groupingid = null;
536 $cm = new stdClass;
537 $cm->id = $wiki->cmid;
538 $cm->groupmode = $wiki->groupmode;
539 $cm->groupingid = $wiki->groupingid;
540 $cm->groupmembersonly = $wiki->groupmembersonly;
541 if (!empty($CFG->enablegroupings) && !empty($cm->groupingid)) {
542 $groupingid = $wiki->groupingid;
546 switch ($wiki->wtype) {
548 case 'student':
549 /// Get all the existing entries for this wiki.
550 $wiki_entries = wiki_get_entries($wiki, 'student');
552 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
553 $sql = "SELECT gm.userid FROM {$CFG->prefix}groups_members gm " .
554 "INNER JOIN {$CFG->prefix}groupings_groups gg ON gm.groupid = gg.groupid " .
555 "WHERE gg.groupingid = $wiki->groupingid ";
557 $groupingmembers = get_records_sql($sql);
560 if ($isteacher and (SITEID != $course->id)) {
562 /// If the user is an editing teacher, or a non-editing teacher not assigned to a group, show all student
563 /// wikis, regardless of creation.
564 if ((SITEID != $course->id) and ($isteacheredit or ($groupmode == NOGROUPS))) {
566 if ($students = get_course_students($course->id)) {
567 /// Default pagename is dependent on the wiki settings.
568 $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
570 foreach ($students as $student) {
571 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid) && empty($groupingmembers[$student->id])) {
572 continue;
574 /// If this student already has an entry, use its pagename.
575 if ($wiki_entries[$student->id]) {
576 $pagename = $wiki_entries[$student->id]->pagename;
578 else {
579 $pagename = $defpagename;
582 $key = 'view.php?id='.$id.'&userid='.$student->id.'&page='.$pagename;
583 $wikis[$key] = fullname($student).':'.$pagename;
587 else if ($groupmode == SEPARATEGROUPS) {
589 if ($students = wiki_get_students($wiki, $mygroupid)) {
590 $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
591 foreach ($students as $student) {
592 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid) && empty($groupingmembers[$student->id])) {
593 continue;
595 /// If this student already has an entry, use its pagename.
596 if ($wiki_entries[$student->id]) {
597 $pagename = $wiki_entries[$student->id]->pagename;
599 else {
600 $pagename = $defpagename;
603 $key = 'view.php?id='.$id.'&userid='.$student->id.'&page='.$pagename;
604 $wikis[$key] = fullname($student).':'.$pagename;
608 else if ($groupmode == VISIBLEGROUPS) {
609 /// Get all students in your group.
610 if ($students = wiki_get_students($wiki, $mygroupid)) {
611 $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
612 foreach ($students as $student) {
613 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid) && empty($groupingmembers[$student->id])) {
614 continue;
616 /// If this student already has an entry, use its pagename.
617 if ($wiki_entries[$student->id]) {
618 $pagename = $wiki_entries[$student->id]->pagename;
620 else {
621 $pagename = $defpagename;
623 $key = 'view.php?id='.$id.'&userid='.$student->id.'&page='.$pagename;
624 $wikis[$key] = fullname($student).':'.$pagename;
627 /// Get all student wikis created, regardless of group.
628 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
629 $sql = 'SELECT w.id, w.userid, w.pagename, u.firstname, u.lastname '
630 .' FROM '.$CFG->prefix.'wiki_entries w '
631 .' INNER JOIN '.$CFG->prefix.'user u ON w.userid = u.id '
632 .' INNER JOIN '.$CFG->prefix.'groups_members gm ON gm.userid = u.id '
633 .' INNER JOIN '.$CFG->prefix.'groupings_groups gg ON gm.groupid = gg.groupid '
634 .' WHERE w.wikiid = '.$wiki->id.' AND gg.groupingid = '.$wiki->groupingid
635 .' ORDER BY w.id';
636 } else {
637 $sql = 'SELECT w.id, w.userid, w.pagename, u.firstname, u.lastname '
638 .' FROM '.$CFG->prefix.'wiki_entries w, '.$CFG->prefix.'user u '
639 .' WHERE w.wikiid = '.$wiki->id.' AND u.id = w.userid '
640 .' ORDER BY w.id';
642 $wiki_entries = get_records_sql($sql);
643 $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
644 foreach ($wiki_entries as $wiki_entry) {
645 $key = 'view.php?id='.$id.'&userid='.$wiki_entry->userid.'&page='.$wiki_entry->pagename;
646 $wikis[$key] = fullname($wiki_entry).':'.$wiki_entry->pagename;
647 if ($currentid == $wiki_entry->id) {
648 $wikis['selected'] = $key;
653 else {
654 /// A user can see other student wikis if they are a member of the same
655 /// group (for separate groups) or there are visible groups, or if this is
656 /// a site-level wiki, and they are an administrator.
657 if (($groupmode == VISIBLEGROUPS) or wiki_is_teacheredit($wiki)) {
658 $viewall = true;
660 else if ($groupmode == SEPARATEGROUPS) {
661 $viewall = mygroupid($course->id);
663 else {
664 $viewall = false;
667 if ($viewall !== false) {
668 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
669 $sql = 'SELECT w.id, w.userid, w.pagename, u.firstname, u.lastname '
670 .' FROM '.$CFG->prefix.'wiki_entries w '
671 .' INNER JOIN '.$CFG->prefix.'user u ON w.userid = u.id '
672 .' INNER JOIN '.$CFG->prefix.'groups_members gm ON gm.userid = u.id '
673 .' INNER JOIN '.$CFG->prefix.'groupings_groups gg ON gm.groupid = gg.groupid '
674 .' WHERE w.wikiid = '.$wiki->id.' AND gg.groupingid = '.$wiki->groupingid
675 .' ORDER BY w.id';
676 } else {
677 $sql = 'SELECT w.id, w.userid, w.pagename, u.firstname, u.lastname '
678 .' FROM '.$CFG->prefix.'wiki_entries w, '.$CFG->prefix.'user u '
679 .' WHERE w.wikiid = '.$wiki->id.' AND u.id = w.userid '
680 .' ORDER BY w.id';
682 $wiki_entries = get_records_sql($sql);
683 $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
684 foreach ($wiki_entries as $wiki_entry) {
685 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid) && empty($groupingmembers[$wiki_entry->userid])) {
686 continue;
689 if (($viewall === true) or groups_is_member($viewall, $wiki_entry->userid)) {
690 $key = 'view.php?id='.$id.'&userid='.$wiki_entry->userid.'&page='.$wiki_entry->pagename;
691 $wikis[$key] = fullname($wiki_entry).':'.$wiki_entry->pagename;
692 if ($currentid == $wiki_entry->id) {
693 $wikis['selected'] = $key;
699 break;
701 case 'group':
702 /// If the user is an editing teacher, or a non-editing teacher not assigned to a group, show all group
703 /// wikis, regardless of creation.
705 /// If user is a member of multiple groups, need to show current group etc?
707 /// Get all the existing entries for this wiki.
708 $wiki_entries = wiki_get_entries($wiki, 'group');
710 if ($groupmode and ($isteacheredit or ($isteacher and !$mygroupid))) {
711 if ($groups = groups_get_all_groups($course->id, null, $groupingid)) {
712 $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
713 foreach ($groups as $group) {
715 /// If this group already has an entry, use its pagename.
716 if (isset($wiki_entries[$group->id])) {
717 $pagename = $wiki_entries[$group->id]->pagename;
719 else {
720 $pagename = $defpagename;
723 $key = 'view.php?id='.$id.($group->id?"&groupid=".$group->id:"").'&page='.$pagename;
724 $wikis[$key] = $group->name.':'.$pagename;
728 //if a studnet with multiple groups in SPG
729 else if ($groupmode == SEPARATEGROUPS){
730 if ($groups = groups_get_all_groups($course->id, $user->id, $groupingid)){
732 $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
733 foreach ($groups as $group) {
734 /// If this group already has an entry, use its pagename.
735 if (isset($wiki_entries[$group->id])) {
736 $pagename = $wiki_entries[$group->id]->pagename;
738 else {
739 $pagename = $defpagename;
741 $key = 'view.php?id='.$id.($group->id?"&groupid=".$group->id:"").'&page='.$pagename;
742 $wikis[$key] = $group->name.':'.$pagename;
748 /// A user can see other group wikis if there are visible groups.
749 else if ($groupmode == VISIBLEGROUPS) {
750 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
751 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
752 .' FROM '.$CFG->prefix.'wiki_entries w '
753 .' INNER JOIN '.$CFG->prefix.'groups g ON g.id = w.groupid '
754 .' INNER JOIN '.$CFG->prefix.'groupings_groups gg ON g.id = gg.groupid '
755 .' WHERE w.wikiid = '.$wiki->id.' AND gg.groupingid = '.$wiki->groupingid
756 .' ORDER BY w.groupid';
757 } else {
758 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
759 .' FROM '.$CFG->prefix.'wiki_entries w, '.$CFG->prefix.'groups g '
760 .' WHERE w.wikiid = '.$wiki->id.' AND g.id = w.groupid '
761 .' ORDER BY w.groupid';
763 $wiki_entries = get_records_sql($sql);
764 $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
765 foreach ($wiki_entries as $wiki_entry) {
766 $key = 'view.php?id='.$id.($wiki_entry->groupid?"&groupid=".$wiki_entry->groupid:"").'&page='.$wiki_entry->pagename;
767 $wikis[$key] = $wiki_entry->gname.':'.$wiki_entry->pagename;
768 if ($currentid == $wiki_entry->id) {
769 $wikis['selected'] = $key;
773 break;
775 case 'teacher':
776 if ($isteacher) {
777 /// If the user is an editing teacher, or a non-editing teacher not assigned to a group, show all
778 /// teacher wikis, regardless of creation.
779 if ($groupmode and ($isteacheredit or ($isteacher and !$mygroupid))) {
780 if ($groups = groups_get_all_groups($course->id, null, $groupingid)) {
781 $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
782 foreach ($groups as $group) {
783 /// If this group already has an entry, use its pagename.
784 if ($wiki_entries[$group->id]) {
785 $pagename = $wiki_entries[$group->id]->pagename;
787 else {
788 $pagename = $defpagename;
791 $key = 'view.php?id='.$id.($group->id?"&groupid=".$group->id:"").'&page='.$pagename;
792 $wikis[$key] = $group->name.':'.$pagename;
796 /// A teacher can see all other group teacher wikis.
797 else if ($groupmode) {
798 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
799 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
800 .' FROM '.$CFG->prefix.'wiki_entries w '
801 .' INNER JOIN '.$CFG->prefix.'groups g ON g.id = w.groupid '
802 .' INNER JOIN '.$CFG->prefix.'groupings_groups gg ON g.id = gg.groupid '
803 .' WHERE w.wikiid = '.$wiki->id.' AND gg.groupingid = '.$wiki->groupingid
804 .' ORDER BY w.groupid';
805 } else {
806 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
807 .' FROM '.$CFG->prefix.'wiki_entries w, '.$CFG->prefix.'groups g '
808 .' WHERE w.wikiid = '.$wiki->id.' AND g.id = w.groupid '
809 .' ORDER BY w.groupid';
811 $wiki_entries = get_records_sql($sql);
812 $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
813 foreach ($wiki_entries as $wiki_entry) {
814 $key = 'view.php?id='.$id.($wiki_entry->groupid?"&groupid=".$wiki_entry->groupid:"").'&page='.$wiki_entry->pagename;
815 $wikis[$key] = $wiki_entry->gname.':'.$wiki_entry->pagename;
816 if ($currentid == $wiki_entry->id) {
817 $wikis['selected'] = $key;
822 else {
823 /// A user can see other teacher wikis if they are a teacher, a member of the same
824 /// group (for separate groups) or there are visible groups.
825 if ($groupmode == VISIBLEGROUPS) {
826 $viewall = true;
828 else if ($groupmode == SEPARATEGROUPS) {
829 $viewall = $mygroupid;
831 else {
832 $viewall = false;
834 if ($viewall !== false) {
835 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
836 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
837 .' FROM '.$CFG->prefix.'wiki_entries w '
838 .' INNER JOIN '.$CFG->prefix.'groups g ON g.id = w.groupid '
839 .' INNER JOIN '.$CFG->prefix.'groupings_groups gg ON g.id = gg.groupid '
840 .' WHERE w.wikiid = '.$wiki->id.' AND gg.groupingid = '.$wiki->groupingid
841 .' ORDER BY w.groupid';
842 } else {
843 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
844 .' FROM '.$CFG->prefix.'wiki_entries w, '.$CFG->prefix.'groups g '
845 .' WHERE w.wikiid = '.$wiki->id.' AND g.id = w.groupid '
846 .' ORDER BY w.groupid';
848 $wiki_entries = get_records_sql($sql);
849 $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
852 foreach ($wiki_entries as $wiki_entry) {
853 if (($viewall === true) or @in_array($wiki_entry->groupid, $viewall)/*$viewall == $wiki_entry->groupid*/) {
854 $key = 'view.php?id='.$id.($wiki_entry->groupid?"&groupid=".$wiki_entry->groupid:"").'&page='.$wiki_entry->pagename;
855 $wikis[$key] = $wiki_entry->gname.':'.$wiki_entry->pagename;
856 if ($currentid == $wiki_entry->id) {
857 $wikis['selected'] = $key;
863 break;
866 return $wikis;
869 function wiki_add_entry(&$wiki, &$course, $userid=0, $groupid=0) {
870 /// Adds a new wiki entry of the specified type, unless already entered.
871 /// No checking is done here. It is assumed that the caller has the correct
872 /// privileges to add this entry.
874 global $USER;
876 /// If this wiki already has a wiki_type entry, return false.
877 if (wiki_get_entry($wiki, $course, $userid, $groupid) !== false) {
878 return false;
881 $wiki_entry = new Object();
883 switch ($wiki->wtype) {
885 case 'student':
886 $wiki_entry->wikiid = $wiki->id;
887 $wiki_entry->userid = $userid ? $userid : $USER->id;
888 $wiki_entry->pagename = wiki_page_name($wiki);
889 $wiki_entry->timemodified = time();
890 break;
892 case 'group':
893 /// Get the groupmode. It's been added to the wiki object.
894 $groupmode = groups_get_activity_groupmode($wiki);
896 ///give the first groupid by default and try
897 $mygroups = mygroupid($course->id);
899 /// If there is a groupmode, get the group id.
900 if ($groupmode) {
901 $groupid = $groupid ? $groupid : $mygroups[0]/*mygroupid($course->id)*/;
903 /// If mode is 'nogroups', then groupid is zero.
904 else {
905 $groupid = 0;
907 $wiki_entry->wikiid = $wiki->id;
908 $wiki_entry->groupid = $groupid;
909 $wiki_entry->pagename = wiki_page_name($wiki);
910 $wiki_entry->timemodified = time();
912 break;
914 case 'teacher':
915 /// Get the groupmode. It's been added to the wiki object.
916 $groupmode = groups_get_activity_groupmode($wiki);
918 /// If there is a groupmode, get the user's group id.
919 if ($groupmode and $groupid == 0) {
920 $mygroupid = mygroupid($course->id);
921 $groupid = $mygroupid[0]/*mygroupid($course->id)*/;
924 $wiki_entry->wikiid = $wiki->id;
925 $wiki_entry->course = $wiki->course;
926 $wiki_entry->groupid = $groupid;
927 $wiki_entry->pagename = wiki_page_name($wiki);
928 $wiki_entry->timemodified = time();
929 break;
931 $wiki_entry->pagename = addslashes($wiki_entry->pagename);
933 return insert_record("wiki_entries", $wiki_entry, true);
936 function wiki_can_add_entry(&$wiki, &$user, &$course, $userid=0, $groupid=0) {
937 /// Returns true or false if the user can add a wiki entry for this wiki.
939 /// Get the groupmode. It's been added to the wiki object.
940 $groupmode = groups_get_activity_groupmode($wiki);
941 $mygroupid = mygroupid($course->id);
943 switch ($wiki->wtype) {
945 case 'student':
946 /// A student can create their own wiki, if they are a member of that course.
947 /// A user can create their own wiki at the site level.
948 if ($userid == 0) {
949 return (wiki_is_student($wiki, $user->id) or wiki_is_student($wiki, $user->id));
951 /// An editing teacher can create any student wiki, or
952 /// a non-editing teacher, if not assigned to a group can create any student wiki, or if assigned to a group can
953 /// create any student wiki in their group.
954 else {
955 return ((($userid == $user->id) and wiki_is_student($wiki, $user->id)) or wiki_is_teacheredit($wiki) or
956 (wiki_is_teacher($wiki) and (!$groupmode or $mygroupid == 0 or (groups_is_member($mygroupid, $userid)))));
958 break;
960 case 'group':
961 /// If mode is 'nogroups', then all participants can add wikis.
962 if (wiki_is_teacheredit($wiki, $user->id)) {
963 return true;
966 if (!$groupmode) {
967 return (wiki_is_student($wiki, $user->id) or wiki_is_teacher($wiki, $user->id));
969 /// If not requesting a group, must be a member of a group.
970 else if ($groupid == 0) {
971 return ($mygroupid != 0);
973 /// If requesting a group, must be an editing teacher, a non-editing teacher with no assigned group,
974 /// or a non-editing teacher requesting their group. or a student in group, but wiki is empty.
975 else {
976 return (wiki_is_teacheredit($wiki) or
977 (wiki_is_teacher($wiki) and ($mygroupid == 0 or @in_array($groupid, $mygroupid))) or
978 (wiki_is_student($wiki, $user->id) and @in_array($groupid, $mygroupid))
981 break;
983 case 'teacher':
984 /// If mode is 'nogroups', then all teachers can add wikis.
985 if (!$groupmode) {
986 return wiki_is_teacher($wiki, $user->id);
988 /// If not requesting a group, must be a member of a group.
989 else if ($groupid == 0) {
990 return ($mygroupid != 0 and wiki_is_teacher($wiki));
992 /// If there is a group mode, non-editing teachers with an assigned group, can only create wikis
993 /// in their group. Non-editing teachers with no assigned group and editing teachers can create any wiki.
994 else {
995 return (wiki_is_teacheredit($wiki) or
996 (wiki_is_teacher($wiki) and ($mygroupid == 0 or @in_array($groupid, $mygroupid))));
998 break;
1001 return false;
1004 function wiki_can_edit_entry(&$wiki_entry, &$wiki, &$user, &$course) {
1005 /// Returns true or false if the user can edit this wiki entry.
1007 $can_edit = false;
1008 $groupmode = groups_get_activity_groupmode($wiki);
1009 $mygroupid = mygroupid($course->id);
1011 /// Editing teacher's and admins can edit all wikis, non-editing teachers can edit wikis in their groups,
1012 /// or all wikis if group mode is 'no groups' or they don't belong to a group.
1013 if (wiki_is_teacheredit($wiki, $user->id) or
1014 ((!$groupmode or $mygroupid == 0) and wiki_is_teacher($wiki, $user->id))) {
1015 $can_edit = true;
1017 else {
1018 switch ($wiki->wtype) {
1020 /// Only a teacher or the owner of a student wiki can edit it.
1021 case 'student':
1022 $can_edit = (($user->id == $wiki_entry->userid) or
1023 ($groupmode and wiki_is_teacher($wiki, $user->id) and
1024 groups_is_member($mygroupid, $wiki_entry->userid)));
1025 break;
1027 case 'group':
1028 /// If there is a groupmode, determine the user's group status.
1029 if ($groupmode) {
1030 /// If the user is a member of the wiki group, they can edit the wiki.
1031 $can_edit = groups_is_member($wiki_entry->groupid, $user->id);
1033 /// If mode is 'nogroups', then all participants can edit the wiki.
1034 else {
1035 $can_edit = (wiki_is_student($wiki, $user->id) or wiki_is_teacher($wiki, $user->id));
1037 break;
1039 case 'teacher':
1040 /// If there is a groupmode, determine the user's group status.
1041 if ($groupmode) {
1042 /// If the user is a member of the wiki group, they can edit the wiki.
1043 $can_edit = (wiki_is_teacher($wiki, $user->id) and groups_is_member($wiki_entry->groupid, $user->id));
1045 else {
1046 $can_edit = wiki_is_teacher($wiki, $user->id);
1048 break;
1051 return $can_edit;
1054 function wiki_user_can_access_student_wiki(&$wiki, $userid, &$course) {
1055 global $USER;
1057 /// Get the groupmode. It's been added to the wiki object.
1058 $groupmode = groups_get_activity_groupmode($wiki);
1059 $usersgroup = mygroupid($course->id);
1060 $isteacher = wiki_is_teacher($wiki, $USER->id);
1062 /// If this user is allowed to access this wiki then return TRUE.
1063 /// *** THIS COULD BE A PROBLEM, IF STUDENTS COULD EVER BE PART OF MORE THAN ONE GROUP ***
1064 /// A user can access a student wiki, if:
1065 /// - it is their wiki,
1066 /// - group mode is VISIBLEGROUPS,
1067 /// - group mode is SEPARATEGROUPS, and the user is a member of the requested user's group,
1068 /// - they are an editing teacher or administrator,
1069 /// - they are a non-editing teacher not assigned to a specific group,
1070 /// - they are a non-editing teacher and group mode is NOGROUPS.
1071 /// - they are an administrator (mostly for site-level wikis).
1072 if (($userid and ($USER->id == $userid)) or ($groupmode == VISIBLEGROUPS) or
1073 (($groupmode == SEPARATEGROUPS) and groups_is_member($usersgroup, $userid)) or
1074 (wiki_is_teacheredit($wiki, $USER->id)) or
1075 (wiki_is_teacher($wiki, $USER->id) and (!$usersgroup or $groupmode == NOGROUPS))) {
1076 $can_access = true;
1078 else {
1079 $can_access = false;
1081 return $can_access;
1084 function wiki_user_can_access_group_wiki(&$wiki, $groupid, &$course) {
1085 global $USER;
1087 /// Get the groupmode. It's been added to the wiki object.
1088 $groupmode = groups_get_activity_groupmode($wiki);
1089 $usersgroup = mygroupid($course->id);
1090 $isteacher = wiki_is_teacher($wiki, $USER->id);
1092 /// A user can access a group wiki, if:
1093 /// - group mode is NOGROUPS,
1094 /// - group mode is VISIBLEGROUPS,
1095 /// - group mode is SEPARATEGROUPS, and they are a member of the requested group,
1096 /// - they are an editing teacher or administrator,
1097 /// - they are a non-editing teacher not assigned to a specific group.
1098 if (($groupmode == NOGROUPS) or ($groupmode == VISIBLEGROUPS) or
1099 (($groupmode == SEPARATEGROUPS) and @in_array($groupid, $usersgroup)/*($usersgroup == $groupid)*/) or
1100 (wiki_is_teacheredit($wiki, $USER->id)) or
1101 (wiki_is_teacher($wiki, $USER->id) and !$usersgroup)) {
1102 $can_access = true;
1104 else {
1105 $can_access = false;
1107 return $can_access;
1110 function wiki_user_can_access_teacher_wiki(&$wiki, $groupid, &$course) {
1111 global $USER;
1113 /// Get the groupmode. It's been added to the wiki object.
1114 $groupmode = groups_get_activity_groupmode($wiki);
1116 /// A user can access a teacher wiki, if:
1117 /// - group mode is NOGROUPS,
1118 /// - group mode is VISIBLEGROUPS,
1119 /// - group mode is SEPARATEGROUPS, and they are a member of the requested group,
1120 /// - they are a teacher or administrator,
1121 if (($groupmode == NOGROUPS) or ($groupmode == VISIBLEGROUPS) or
1122 (($groupmode == SEPARATEGROUPS) and (@in_array($groupid, mygroupid($course->id))/*mygroupid($course->id) == $groupid*/)) or
1123 (wiki_is_teacher($wiki, $USER->id))){
1124 $can_access = true;
1126 else {
1127 $can_access = false;
1129 return $can_access;
1132 function wiki_get_owner(&$wiki_entry) {
1133 if ($wiki_entry->userid > 0) {
1134 $user = get_record('user', 'id', $wiki_entry->userid);
1135 $owner = fullname($user);
1137 else if ($wiki_entry->groupid > 0) {
1138 $owner = groups_get_group_name($wiki_entry->groupid); //TODO:check.
1140 else if ($wiki_entry->course > 0) {
1141 $course = get_record('course', 'id', $wiki_entry->course);
1142 $owner = $course->shortname;
1144 else {
1145 $owner = '- '.get_string("ownerunknown","wiki").' -';
1147 return $owner;
1150 function wiki_print_search_form($cmid, $search="", $userid, $groupid, $return=false) {
1151 global $CFG;
1152 # TODO: Add Group and User !!!
1153 $output = "<form id=\"search\" action=\"$CFG->wwwroot/mod/wiki/view.php\">";
1154 $output .="<fieldset class='invisiblefieldset'>";
1155 $output .= "<span style='font-size:0.6em;'>";
1156 $output .= "<input value=\"".get_string("searchwiki", "wiki").":\" type=\"submit\" />";
1157 $output .= "<input name=\"id\" type=\"hidden\" value=\"$cmid\" />";
1158 $output = $output.($groupid?"<input name=\"groupid\" type=\"hidden\" value=\"$groupid\" />":"");
1159 $output = $output.($userid?"<input name=\"userid\" type=\"hidden\" value=\"$userid\" />":"");
1160 $output .= "<input name=\"q\" type=\"text\" size=\"20\" value=\"".s($search)."\" />".' ';
1161 $output .= "</span>";
1162 $output .= "<input name=\"page\" type=\"hidden\" value=\"SearchPages\" />";
1163 $output .= "</fieldset>";
1164 $output .= "</form>";
1166 if ($return) {
1167 return $output;
1169 echo $output;
1172 function wiki_print_wikilinks_block($cmid, $binary=false, $return=false) {
1173 /// Prints a link-list of special wiki-pages
1174 global $CFG, $ewiki_title;
1176 $links=array();
1178 $links["SiteMap"]=get_string("sitemap", "wiki");
1179 $links["PageIndex"]=get_string("pageindex", "wiki");
1180 $links["NewestPages"]=get_string("newestpages", "wiki");
1181 $links["MostVisitedPages"]=get_string("mostvisitedpages", "wiki");
1182 $links["MostOftenChangedPages"]=get_string("mostoftenchangedpages", "wiki");
1183 $links["UpdatedPages"]=get_string("updatedpages", "wiki");
1184 $links["OrphanedPages"]=get_string("orphanedpages", "wiki");
1185 $links["WantedPages"]=get_string("wantedpages", "wiki");
1186 $links["WikiExport"]=get_string("wikiexport", "wiki");
1187 if($binary) {
1188 $links["FileDownload"]=get_string("filedownload", "wiki");
1190 popup_form(EWIKI_SCRIPT, $links, "wikilinks", "", get_string("choosewikilinks", "wiki"), "", "", $return);
1193 function wiki_print_page_actions($cmid, $specialpages, $page, $action, $binary=false, $canedit=true) {
1194 /// Displays actions which can be performed on the page
1196 $page=array();
1198 // Edit this Page
1199 if (in_array($action, array("edit", "links", "info", "attachments"))) {
1200 $page["view/$page"]=get_string("viewpage","wiki");
1202 if ($canedit && !in_array($page, $specialpages) && $action != "edit") {
1203 $page["edit/$page"]=get_string("editthispage","wiki");
1205 if ($action != "links") {
1206 $page["links/$page"]=get_string("backlinks","wiki");
1208 if ($canedit && !in_array($page, $specialpages) && $action!="info") {
1209 $page["info/$page"]=get_string("pageinfo","wiki");
1211 if($canedit && $binary && !in_array($page, $specialpages) && $action != "attachments") {
1212 $page["attachments/$page"]=get_string("attachments","wiki");
1215 popup_form(EWIKI_SCRIPT, $page, "wikiactions", "", get_string("action", "wiki"), "", "", false);
1218 function wiki_print_administration_actions($wiki, $cmid, $userid, $groupid, $page, $noeditor, $course) {
1219 /// Displays actions which can be performed on the page
1221 /// Create the URL
1222 $ewscript = 'admin.php?id='.$cmid;
1223 if (isset($userid) && $userid!=0) $ewscript .= '&amp;userid='.$userid;
1224 if (isset($groupid) && $groupid!=0) $ewscript .= '&amp;groupid='.$groupid;
1225 if (isset($page)) $ewscript .= '&amp;page='.$page;
1226 $ewscript.="&amp;action=";
1229 /// Build that action array according to wiki flags.
1230 $action = array();
1231 $isteacher = wiki_is_teacher($wiki);
1233 if ($wiki->setpageflags or $isteacher) {
1234 $action['setpageflags'] = get_string('setpageflags', 'wiki');
1236 if ($wiki->removepages or $isteacher) {
1237 $action['removepages'] = get_string('removepages', 'wiki');
1239 if ($wiki->strippages or $isteacher) {
1240 $action['strippages'] = get_string('strippages', 'wiki');
1242 if ($wiki->revertchanges or $isteacher) {
1243 $action['revertpages'] = get_string('revertpages', 'wiki');
1246 if($noeditor) {
1247 $action["checklinks"]=get_string("checklinks", "wiki");
1249 popup_form($ewscript, $action, "wikiadministration", "", get_string("chooseadministration", "wiki"), "", "", false);
1252 function wiki_admin_get_flagarray() {
1253 $ret = array(
1254 EWIKI_DB_F_TEXT => get_string("flagtxt","wiki"),
1255 EWIKI_DB_F_BINARY => get_string("flagbin","wiki"),
1256 EWIKI_DB_F_DISABLED => get_string("flagoff","wiki"),
1257 EWIKI_DB_F_HTML => get_string("flaghtm","wiki"),
1258 EWIKI_DB_F_READONLY => get_string("flagro","wiki"),
1259 EWIKI_DB_F_WRITEABLE => get_string("flagwr","wiki"),
1262 return $ret;
1265 ///////// Ewiki Administration. Mostly taken from the ewiki/tools folder and changed
1266 function wiki_admin_setpageflags_list($pageflagstatus) {
1267 $FD = wiki_admin_get_flagarray();
1268 $table = new Object();
1269 $table->head = array(get_string("pagename","wiki"), get_string("flags","wiki"));
1270 if($pageflagstatus) {
1271 $table->head[]=get_string("status","wiki");
1274 $result = ewiki_database("GETALL", array("version", "flags"));
1275 while ($row = $result->get()) {
1276 $id = $row["id"];
1277 $data = ewiki_database("GET", $row);
1279 $cell_pagename="";
1280 $cell_flags="";
1281 if ($data["flags"] & EWIKI_DB_F_TEXT) {
1282 $cell_pagename .= '<a href="' . EWIKI_SCRIPT . $id . '">';
1283 } else {
1284 $cell_pagename .= '<a href="' . EWIKI_SCRIPT_BINARY . $id . '">';
1286 $cell_pagename .= s($id) . '</a> / '.get_string("version","wiki").": ".$row["version"];
1288 foreach ($FD as $n=>$str) {
1289 $cell_flags .='<input type="checkbox" name="flags['. rawurlencode($id)
1290 . '][' . $n . ']" value="1" '
1291 . (($data["flags"] & $n) ? "checked=\"checked\"" : "")
1292 . ' />'.$str. ' ';
1294 if($pageflagstatus) {
1295 $table->data[]=array($cell_pagename, $cell_flags, $pageflagstatus[$id]);
1296 } else {
1297 $table->data[]=array($cell_pagename, $cell_flags);
1300 return $table;
1303 function wiki_admin_setpageflags($pageflags) {
1304 $FD = wiki_admin_get_flagarray();
1306 $status=array();
1307 if($pageflags) {
1308 foreach($pageflags as $page=>$fa) {
1310 $page = rawurldecode($page);
1312 $flags = 0;
1313 $fstr = "";
1314 foreach($fa as $num=>$isset) {
1315 if ($isset) {
1316 $flags += $num;
1317 $fstr .= ($fstr?",":""). $FD[$num];
1321 #$status[$page] .= "{$flags}=[{$fstr}]";
1323 $data = ewiki_database("GET", array("id" => $page));
1325 if ($data["flags"] != $flags) {
1326 $data["flags"] = $flags;
1327 $data["author"] = "ewiki-tools, " . ewiki_author();
1328 $data["version"]++;
1329 ewiki_database("WRITE", $data);
1330 $status[$page] = "<b>".get_string("flagsset","wiki")."</b> ".$status[$page];
1334 return $status;
1338 function wiki_admin_remove_list($listall="") {
1339 /// Table header
1340 $table = new Object();
1341 $table->head = array("&nbsp;", get_string("pagename","wiki"), get_string("errororreason","wiki"));
1343 /// Get all pages
1344 $result = ewiki_database("GETALL", array("version"));
1345 $selected = array();
1347 /// User wants to see all pages
1348 if ($listall) {
1349 while ($row = $result->get()) {
1350 $selected[$row["id"]] = get_string("listall","wiki")."<br />";
1353 while ($page = $result->get()) {
1354 $id = $page["id"];
1355 $page = ewiki_database("GET", array("id"=>$id));
1356 $flags = $page["flags"];
1357 #print "$id ".strlen(trim(($page["content"])))."<br />";
1359 if (!strlen(trim(($page["content"]))) && !($flags & EWIKI_DB_F_BINARY)) {
1360 @$selected[$id] .= get_string("emptypage","wiki")."<br />";
1363 // Check for orphaned pages
1364 $result2 = ewiki_database("SEARCH", array("content" => $id));
1365 $orphanedpage=true;
1366 if ($result2 && $result2->count()) {
1367 while ($row = $result2->get()) {
1368 $checkcontent = ewiki_database("GET", array("id"=>$row["id"]));
1369 $checkcontent = strtolower($checkcontent["content"]);
1371 if(strpos($checkcontent, strtolower($id)) !== false) {
1372 $orphanedpage=false;
1375 #echo "rc({$row['id']})==>($id): $check2 <br />";
1379 /// Some more reasons for Deletion...
1380 if ($orphanedpage && $id!=EWIKI_PAGE_INDEX &&!($flags & EWIKI_DB_F_BINARY)) {
1381 @$selected[$id] .= get_string("orphanedpage","wiki")."<br />";
1384 if ($flags & EWIKI_DB_F_DISABLED) {
1385 @$selected[$id] .= get_string("disabledpage","wiki")."<br />";
1388 if (($flags & 3) == 3) {
1389 @$selected[$id] .= get_string("errorbinandtxt","wiki")."<br />";
1392 if (!($flags & 3)) {
1393 @$selected[$id] .= get_string("errornotype","wiki")."<br />";
1396 if ($flags & EWIKI_DB_F_HTML) {
1397 @$selected[$id] .= get_string("errorhtml","wiki")."<br />";
1400 if (($flags & EWIKI_DB_F_READONLY) && !($flags & EWIKI_DB_F_BINARY)) {
1401 @$selected[$id] .= get_string("readonly","wiki")."<br />";
1404 if (($flags & EWIKI_DB_F_READONLY) && ($flags & EWIKI_DB_F_WRITEABLE)) {
1405 @$selected[$id] .= get_string("errorroandwr","wiki")."<br />";
1408 if (strlen($page["content"]) >= 65536) {
1409 @$selected[$id] .= get_string("errorsize","wiki")."<br />";
1412 if (strpos($page["refs"], "\n".get_string("deletemewikiword","wiki")."\n")!==false) {
1413 @$selected[$id] .= get_string("deletemewikiwordfound","wiki",get_string("deletemewikiword","wiki"))."<br />";
1417 foreach ($selected as $id => $reason) {
1418 $table_checkbox='<input type="checkbox" value="'.rawurlencode($id).'" name="pagestodelete[]" />';
1420 #-- link & id
1421 if (strpos($id, EWIKI_IDF_INTERNAL) === false) {
1422 $table_page='<a href="' . ewiki_script("", $id) . '">';
1423 } else {
1424 $table_page='<a href="' . ewiki_script_binary("", $id) . '">';
1426 $table_page .= s($id) . '</a>';
1428 #-- print reason
1429 $table_reason=$reason;
1431 $table->data[]=array($table_checkbox, $table_page, $table_reason);
1434 return $table;
1437 /// This function actually removes the pages
1438 function wiki_admin_remove($pagestodelete, $course, $wiki, $userid, $groupid) {
1439 $ret="";
1440 foreach ($pagestodelete as $id) {
1442 $id = rawurldecode($id);
1444 $data = ewiki_database("GET", array("id"=>$id));
1445 for ($version=1; $version<=$data["version"]; $version++) {
1446 ewiki_database("DELETE", array("id"=>$id, "version"=>$version));
1447 if($data["flags"] & EWIKI_DB_F_BINARY) {
1448 $filepath=moodle_binary_get_path($id, $data["meta"], $course, $wiki, $userid, $groupid);
1449 @unlink("$filepath");
1454 return $ret;
1457 function wiki_admin_strip_list($pagestostrip="",$version="",$err="") {
1458 /// Table header
1459 $table = new Object();
1460 $table->head = array("&nbsp;", get_string("pagename","wiki"), get_string("deleteversions","wiki"));
1462 $vc=ewiki_database("COUNTVERSIONS", array());
1463 $result = ewiki_database("GETALL",array());
1464 $i=0;
1465 while ($row = $result->get()) {
1466 $id = $row["id"];
1467 if($vc[$id]>1) {
1468 $error="";
1469 if($err[$id]) {
1470 $error=" ".join(", ",$err[$id]);
1472 $checked="";
1473 if($pagestostrip=="" || $pagestostrip[$i]) {
1474 $checked=" checked=\"checked\"";
1476 if($version=="") {
1477 $versiondefault="1-".($row["version"]-1);
1478 } else {
1479 $versiondefault=$version[$i];
1481 $table->data[]=array('<input type="checkbox" value="'.rawurlencode($id).'" name="pagestostrip['.$i.']" '.$checked.' />',
1482 '<A HREF="'.EWIKI_SCRIPT.$id.'">'.s($id).'</A> / '.get_string("version","wiki").": ".$row["version"],
1483 '<input name="version['.$i.']" value="'.$versiondefault.'" size="7" />'.$error);
1486 $i++;
1488 return $table;
1491 function wiki_admin_strip_versions($pagestostrip, $version, &$err) {
1492 $ret=array();
1493 foreach ($pagestostrip as $key => $id_ue) {
1495 $id = rawurldecode($id_ue);
1496 if (preg_match('/^(\d+)[-\s._:]+(\d+)$/', trim($version[$key]), $uu)) {
1497 $versA = $uu[1];
1498 $versZ = $uu[2];
1500 // Let the last Version in the database
1501 $checkdata = ewiki_database("GET", array("id" => $id));
1502 if($versZ>=$checkdata["version"]) {
1503 $err[$id][] = get_string("versionrangetoobig","wiki");
1504 } else {
1505 if($versA<=$versZ) {
1506 for ($v=$versA; $v<=$versZ; $v++) {
1507 $ret[$id][]=$v;
1509 } else {
1510 $err[$id][]=get_string("wrongversionrange","wiki",$version[$key]);
1514 else {
1515 $err[$id][]=get_string("wrongversionrange","wiki",$version[$key]);
1518 return $ret;
1521 function wiki_admin_strip($pagestostrip) {
1522 /// Purges old page-versions
1523 foreach($pagestostrip as $id => $versions) {
1524 foreach($versions as $version) {
1525 ewiki_database("DELETE", array("id"=>$id, "version"=>$version));
1530 function wiki_admin_checklinks_list() {
1531 $ret=array();
1532 $result = ewiki_database("GETALL",array());
1533 while ($row = $result->get()) {
1534 if(!($row["flags"] & EWIKI_DB_F_BINARY)) {
1535 $index=s($row["id"]);
1536 $ret[$index] = $row["id"];
1539 return $ret;
1542 function wiki_admin_checklinks($pagetocheck) {
1543 /// Checks http:// Links
1544 $ret="";
1545 if($pagetocheck) {
1546 $get = ewiki_database("GET", array("id" => $pagetocheck));
1547 $content = $get["content"];
1549 preg_match_all('_(http.?://[^\s"\'<>#,;]+[^\s"\'<>#,;.])_', $content, $links);
1550 $badlinks = array();
1551 if(!$links[1]) {
1552 $ret = get_string("nolinksfound","wiki")."<br /><br />";
1553 } else {
1554 foreach ($links[1] as $href) {
1555 #print "[ $href ]";
1556 #$d = @implode("", @file($href));
1557 $d="";
1558 if($checkfd = @fopen($href, 'r')) {
1559 fclose($checkfd);
1560 $d="OK";
1562 if (empty($d) || !strlen(trim($d)) || stristr("not found", $d) || stristr("error 404", $d)) {
1563 $ret.="[".get_string("linkdead","wiki")."] $href <br />\n";
1564 $badlinks[] = $href;
1565 } else {
1566 $ret.="[".get_string("linkok","wiki")."] $href <br />\n";
1571 /// Remove old Notices
1572 $content = eregi_replace(' µµ__~\['.get_string("offline","wiki").'\]__µµ ','', $content);
1574 #-- replace dead links
1575 foreach ($badlinks as $href) {
1576 $content = preg_replace("\377^(.*)($href)\377m", '$1 µµ__~['.get_string("offline","wiki").']__µµ $2', $content);
1579 #-- compare against db content
1580 if ($content != $get["content"]) {
1581 $get["content"] = $content;
1582 $get["version"]++;
1583 $get["author"] = ewiki_author("ewiki_checklinks");
1584 $get["lastmodified"] = time();
1586 ewiki_database("WRITE", $get);
1589 return $ret;
1592 function wiki_admin_revert($proceed, $authorfieldpattern, $changesfield, $howtooperate, $deleteversions) {
1593 $ret="";
1594 #-- params
1595 $m_time = $changesfield * 3600;
1596 $depth = $deleteversions - 1;
1597 $depth = ($depth>0?$depth:0);
1599 #-- walk through
1600 $result = ewiki_database("GETALL", array("id", "author", "lastmodified"));
1601 while ($row = $result->get()) {
1602 $id = $row["id"];
1603 #-- which versions to check
1604 $verZ = $row["version"];
1605 if ($howtooperate=="lastonly") {
1606 $verA = $verZ;
1608 else {
1609 $verA = $verZ-$depth;
1610 if ($verA <= 0) {
1611 $verA = 1;
1615 for ($ver=$verA; $ver<=$verZ; $ver++) {
1616 #-- load current $ver database entry
1617 if ($verA != $verZ) {
1618 $row = ewiki_database("GET", array("id"=>$id, "version"=>$ver));
1621 #-- match
1622 if (stristr($row["author"], $authorfieldpattern) && ($row["lastmodified"] + $m_time > time())) {
1623 $ret .= "$id (".get_string("versionstodelete","wiki").": ";
1624 #-- delete multiple versions
1625 if ($howtooperate=="allsince") {
1626 while ($ver<=$verZ) {
1627 $ret .= " $ver";
1628 if ($proceed) {
1629 ewiki_database("DELETE", array("id"=>$id, "version"=>$ver));
1631 $ver++;
1634 #-- or just the affected one
1635 else {
1636 $ret .= " $ver";
1637 if ($proceed) {
1638 ewiki_database("DELETE", $row);
1641 $ret .= ")<br />";
1642 break;
1644 } #-- for($ver)
1645 } #-- while($row)
1646 return $ret;
1650 function wiki_get_view_actions() {
1651 return array('view','view all');
1654 function wiki_get_post_actions() {
1655 return array('hack');
1660 * Obtains an editing lock on a wiki page.
1661 * @param int $wikiid ID of wiki object.
1662 * @param string $pagename Name of page.
1663 * @return array Two-element array with a boolean true (if lock has been obtained)
1664 * or false (if lock was held by somebody else). If lock was held by someone else,
1665 * the values of the wiki_locks entry are held in the second element; if lock was
1666 * held by current user then the the second element has a member ->id only.
1668 function wiki_obtain_lock($wikiid,$pagename) {
1669 global $USER;
1671 // Check for lock
1672 $alreadyownlock=false;
1673 if($lock=get_record('wiki_locks','pagename',$pagename,'wikiid', $wikiid)) {
1674 // Consider the page locked if the lock has been confirmed within WIKI_LOCK_PERSISTENCE seconds
1675 if($lock->lockedby==$USER->id) {
1676 // Cool, it's our lock, do nothing except remember it in session
1677 $lockid=$lock->id;
1678 $alreadyownlock=true;
1679 } else if(time()-$lock->lockedseen < WIKI_LOCK_PERSISTENCE) {
1680 return array(false,$lock);
1681 } else {
1682 // Not locked any more. Get rid of the old lock record.
1683 if(!delete_records('wiki_locks','pagename',$pagename,'wikiid', $wikiid)) {
1684 error('Unable to delete lock record');
1689 // Add lock
1690 if(!$alreadyownlock) {
1691 // Lock page
1692 $newlock=new stdClass;
1693 $newlock->lockedby=$USER->id;
1694 $newlock->lockedsince=time();
1695 $newlock->lockedseen=$newlock->lockedsince;
1696 $newlock->wikiid=$wikiid;
1697 $newlock->pagename=$pagename;
1698 if(!$lockid=insert_record('wiki_locks',$newlock)) {
1699 error('Unable to insert lock record');
1703 // Store lock information in session so we can clear it later
1704 if(!array_key_exists(SESSION_WIKI_LOCKS,$_SESSION)) {
1705 $_SESSION[SESSION_WIKI_LOCKS]=array();
1707 $_SESSION[SESSION_WIKI_LOCKS][$wikiid.'_'.$pagename]=$lockid;
1708 $lockdata=new StdClass;
1709 $lockdata->id=$lockid;
1710 return array(true,$lockdata);
1714 * If the user has an editing lock, releases it. Has no effect otherwise.
1715 * Note that it doesn't matter if this isn't called (as happens if their
1716 * browser crashes or something) since locks time out anyway. This is just
1717 * to avoid confusion of the 'what? it says I'm editing that page but I'm
1718 * not, I just saved it!' variety.
1719 * @param int $wikiid ID of wiki object.
1720 * @param string $pagename Name of page.
1722 function wiki_release_lock($wikiid,$pagename) {
1723 if(!array_key_exists(SESSION_WIKI_LOCKS,$_SESSION)) {
1724 // No locks at all in session
1725 return;
1728 $key=$wikiid.'_'.$pagename;
1730 if(array_key_exists($key,$_SESSION[SESSION_WIKI_LOCKS])) {
1731 $lockid=$_SESSION[SESSION_WIKI_LOCKS][$key];
1732 unset($_SESSION[SESSION_WIKI_LOCKS][$key]);
1733 if(!delete_records('wiki_locks','id',$lockid)) {
1734 error("Unable to delete lock record.");
1740 * Returns all other caps used in module
1742 function wiki_get_extra_capabilities() {
1743 return array('moodle/site:accessallgroups', 'moodle/site:viewfullnames');