"MDL-16597, improve maxfile handling, and position creating folder dialog by PageX...
[moodle.git] / mod / wiki / lib.php
CommitLineData
e5cc530b 1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
39fcb981 17
e5cc530b 18/**
19 * Library of functions and constants for module wiki
20 * (replace wiki with the name of your module and delete this line)
21 *
22 * @package mod-wiki
23 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
39fcb981 26
e5cc530b 27/** @global array $WIKI_TYPES */
17da2e6f 28global $WIKI_TYPES;
713e7568 29$WIKI_TYPES = array ('teacher' => get_string('defaultcourseteacher'),
39fcb981 30 'group' => get_string('groups',"wiki"),
713e7568 31 'student' => get_string('defaultcoursestudent') );
4a9df373 32define("EWIKI_ESCAPE_AT", 0); # For the algebraic filter
39fcb981 33
22e846cd 34// How long locks stay around without being confirmed (seconds)
4db1861a 35define("WIKI_LOCK_PERSISTENCE",120);
22e846cd 36
37// How often to confirm that you still want a lock
4db1861a 38define("WIKI_LOCK_RECONFIRM",60);
22e846cd 39
4db1861a 40// Session variable used to store wiki locks
41define('SESSION_WIKI_LOCKS','wikilocks');
22e846cd 42
ee3cc995 43/*** Moodle 1.7 compatibility functions *****
ee3cc995 44 ********************************************/
e5cc530b 45
46/**
47 * @todo add some $cm caching if needed
48 * @param object $wiki
49 * @return object
50 */
ee3cc995 51function wiki_context($wiki) {
52 //TODO: add some $cm caching if needed
53 if (is_object($wiki)) {
54 $wiki = $wiki->id;
55 }
56 if (! $cm = get_coursemodule_from_instance('wiki', $wiki)) {
4d6ba0f0 57 print_error('invalidcoursemodule');
ee3cc995 58 }
59
60 return get_context_instance(CONTEXT_MODULE, $cm->id);
61}
62
e5cc530b 63/**
64 * @param object $wiki
65 * @param int $userid
66 * @return bool
67 */
ee3cc995 68function wiki_is_teacher($wiki, $userid=NULL) {
69 return has_capability('mod/wiki:manage', wiki_context($wiki), $userid);
70}
e5cc530b 71/**
72 * @param object $wiki
73 * @param int $userid
74 * @return bool
75 */
ee3cc995 76function wiki_is_teacheredit($wiki, $userid=NULL) {
33e7885e 77 return has_capability('mod/wiki:manage', wiki_context($wiki), $userid)
78 and has_capability('moodle/site:accessallgroups', wiki_context($wiki), $userid);
ee3cc995 79}
e5cc530b 80/**
81 * @param object $wiki
82 * @param int $userid
83 * @return bool
84 */
ee3cc995 85function wiki_is_student($wiki, $userid=NULL) {
86 return has_capability('mod/wiki:participate', wiki_context($wiki), $userid);
87}
e5cc530b 88/**
89 * @param object $wiki
90 * @param string $groups
91 * @param string $sort
92 * @param string $fields
93 * @return array
94 */
4da8ff66 95function wiki_get_students($wiki, $groups='', $sort='u.lastaccess', $fields='u.*') {
96 return $users = get_users_by_capability(wiki_context($wiki), 'mod/wiki:participate', $fields, $sort, '', '', $groups);
ee3cc995 97}
98
99/* end of compatibility functions */
100
e5cc530b 101/**
102 * Given an object containing all the necessary data,
103 * (defined by the form in mod_form.php) this function
104 * will create a new instance and return the id number
105 * of the new instance.
106 *
107 * @global object
108 * @param object $wiki
109 * @return bool|int
110 */
39fcb981 111function wiki_add_instance($wiki) {
c18269c7 112 global $DB;
e5cc530b 113
39fcb981 114 $wiki->timemodified = time();
115
116 # May have to add extra stuff in here #
117
526efb55 118 /// Determine the pagename for this wiki and save.
119 $wiki->pagename = wiki_page_name($wiki);
c513f599 120
c18269c7 121 return $DB->insert_record("wiki", $wiki);
39fcb981 122}
123
e5cc530b 124/**
125 * Given an object containing all the necessary data,
126 * (defined by the form in mod_form.php) this function
127 * will update an existing instance with new data.
128 *
129 * @global object
130 * @param object @wiki
131 * @return bool
132 */
39fcb981 133function wiki_update_instance($wiki) {
c18269c7 134 global $DB;
39fcb981 135
526efb55 136 /// Determine the pagename for this wiki.
137 $wiki->pagename = wiki_page_name($wiki);
39fcb981 138
139 $wiki->timemodified = time();
140 $wiki->id = $wiki->instance;
c18269c7 141 return $DB->update_record("wiki", $wiki);
39fcb981 142}
143
e5cc530b 144/**
145 * Delete all Directories recursively
146 *
147 * @param string $basedir
148 */
39fcb981 149function wiki_rmdir($basedir) {
150 $handle = @opendir($basedir);
151 if($handle) {
152 while (false!==($folder = readdir($handle))) {
ee3cc995 153 if($folder != "." && $folder != ".." && $folder != "CVS") {
39fcb981 154 wiki_rmdir("$basedir/$folder"); // recursive
8f0cd6ef 155 }
39fcb981 156 }
157 closedir($handle);
158 }
159 @rmdir($basedir);
160}
161
e5cc530b 162/**
163 * Given an ID of an instance of this module,
164 * this function will permanently delete the instance
165 * and any data that depends on it.
166 *
167 * @global stdObject
168 * @global object
169 * @param int $id
170 * @return bool
171 */
39fcb981 172function wiki_delete_instance($id) {
56da74f3 173 global $CFG, $DB, $OUTPUT;
8f0cd6ef 174
c18269c7 175 if (! $wiki = $DB->get_record("wiki", array("id"=>$id))) {
39fcb981 176 return false;
177 }
178
179 $result = true;
180
181 #Delete Files
182### Should probably check regardless of this setting in case its been changed...
183 if($wiki->ewikiacceptbinary) {
184 if ($basedir = $CFG->dataroot."/".$wiki->course."/".$CFG->moddata."/wiki/$id") {
185 if ($files = get_directory_list($basedir)) {
186 foreach ($files as $file) {
187 #if ($file != $exception) {
188 unlink("$basedir/$file");
56da74f3 189 echo $OUTPUT->notification("Existing file '$file' has been deleted!");
39fcb981 190 #}
191 }
192 }
193 #if (!$exception) { // Delete directory as well, if empty
8f0cd6ef 194 wiki_rmdir("$basedir");
39fcb981 195 #}
8f0cd6ef 196 }
39fcb981 197 }
8f0cd6ef 198
39fcb981 199 # Delete any dependent records here #
c18269c7 200 if(!$DB->delete_records("wiki_locks", array("wikiid"=>$wiki->id))) {
22e846cd 201 $result = false;
202 }
203
c18269c7 204 if (! $DB->delete_records("wiki", array("id"=>$wiki->id))) {
39fcb981 205 $result = false;
206 }
207
208 /// Delete all wiki_entries and wiki_pages.
209 if (($wiki_entries = wiki_get_entries($wiki)) !== false) {
210 foreach ($wiki_entries as $wiki_entry) {
c18269c7 211 if (! $DB->delete_records("wiki_pages", array("wiki"=>$wiki_entry->id))) {
39fcb981 212 $result = false;
213 }
c18269c7 214 if (! $DB->delete_records("wiki_entries", array("id"=>$wiki_entry->id))) {
39fcb981 215 $result = false;
216 }
217 }
218 }
8f0cd6ef 219
39fcb981 220 return $result;
221}
222
e5cc530b 223/**
224 * Return a small object with summary information about what a
225 * user has done with a given particular instance of this module
226 * Used for user activity reports.
227 * $return->time = the time they did it
228 * $return->info = a short text description
229 *
230 * @param object $course
231 * @param object $user
232 * @param object $mod
233 * @param object $wiki
234 * @return null
235 */
39fcb981 236function wiki_user_outline($course, $user, $mod, $wiki) {
39fcb981 237
763692fd 238 $return = NULL;
39fcb981 239 return $return;
240}
241
e5cc530b 242/**
243 * Print a detailed representation of what a user has done with
244 * a given particular instance of this module, for user activity reports.
245 *
246 * @param object $course
247 * @param object $user
248 * @param object $mod
249 * @param object $wiki
250 * @return bool true
251 */
39fcb981 252function wiki_user_complete($course, $user, $mod, $wiki) {
39fcb981 253 return true;
254}
255
e5cc530b 256/**
257 * Given a course and a time, this module should find recent activity
258 * that has occurred in wiki activities and print it out.
259 * Return true if there was output, or false is there was none.
260 *
261 * @global stdClass
262 * @global object
263 * @param object $course
264 * @param bool $isteacher
265 * @param int $timestart
266 * @return bool
267 */
39fcb981 268function wiki_print_recent_activity($course, $isteacher, $timestart) {
9ab0a4fa 269 global $CFG, $DB, $OUTPUT;
27978302 270
655b09ca 271 $sql = "SELECT l.*, cm.instance
272 FROM {log} l JOIN {course_modules} cm ON l.cmid = cm.id
273 WHERE l.time > ? AND l.course = ?
274 AND l.module = 'wiki' AND action LIKE 'edit%'
275 ORDER BY l.time ASC";
27978302 276
655b09ca 277 if (!$logs = $DB->get_records_sql($sql, array($timestart, $course->id))){
1fb5d4b0 278 return false;
279 }
280
dd97c328 281 $modinfo = get_fast_modinfo($course);
282 $wikis = array();
283
1fb5d4b0 284 foreach ($logs as $log) {
dd97c328 285 $cm = $modinfo->instances['wiki'][$log->instance];
286 if (!$cm->uservisible) {
287 continue;
1fb5d4b0 288 }
dd97c328 289
b09f731c 290 /// Process log->url and rebuild it here to properly clean the pagename - MDL-15896
291 $extractedpage = preg_replace('/^.*&page=/', '', $log->url);
292 $log->url = preg_replace('/page=.*$/', 'page='.urlencode($extractedpage), $log->url);
293
dd97c328 294 $wikis[$log->info] = wiki_log_info($log);
295 $wikis[$log->info]->pagename = $log->info;
296 $wikis[$log->info]->time = $log->time;
297 $wikis[$log->info]->url = str_replace('&', '&amp;', $log->url);
1fb5d4b0 298 }
39fcb981 299
dd97c328 300 if (!$wikis) {
301 return false;
302 }
9ab0a4fa 303 echo $OUTPUT->heading(get_string("updatedwikipages", 'wiki').':', 3);
dd97c328 304 foreach ($wikis as $wiki) {
305 print_recent_activity_note($wiki->time, $wiki, $wiki->pagename,
306 $CFG->wwwroot.'/mod/wiki/'.$wiki->url);
1fb5d4b0 307 }
dd97c328 308
309 return false;
1fb5d4b0 310}
311
e5cc530b 312/**
313 * @global stdClass
314 * @global object
315 * @param string $log
316 * @return array
317 */
1fb5d4b0 318function wiki_log_info($log) {
655b09ca 319 global $CFG, $DB;
320 return $DB->get_record_sql("SELECT u.firstname, u.lastname
321 FROM {user} u
322 WHERE u.id = ?", array($log->userid));
39fcb981 323}
324
e5cc530b 325/**
326 * Function to be run periodically according to the moodle cron
327 * This function searches for things that need to be done, such
328 * as sending out mail, toggling flags etc ...
329 *
330 * @global object
331 * @return bool
332 */
39fcb981 333function wiki_cron () {
655b09ca 334 global $DB;
39fcb981 335
22e846cd 336 // Delete expired locks
655b09ca 337 $result = $DB->delete_records_select('wiki_locks','lockedseen < '.(time()-WIKI_LOCK_PERSISTENCE));
39fcb981 338
22e846cd 339 return $result;
39fcb981 340}
341
e5cc530b 342/**
343 * Returns the users with data in one wiki
344 * (users with records in wiki_pages and wiki_entries)
345 *
346 * @global stdClass
347 * @global object
348 * @param int $wikiid
349 * @return array
350 */
39fcb981 351function wiki_get_participants($wikiid) {
e5cc530b 352
655b09ca 353 global $CFG, $DB;
472a28ca 354
355 //Get users from wiki_pages
655b09ca 356 $st_pages = $DB->get_records_sql("SELECT DISTINCT u.id, u.id
357 FROM {user} u, {wiki_entries} e, {wiki_pages} p
358 WHERE e.wikiid = ? and
359 p.wiki = e.id and
360 u.id = p.userid", array($wikiid));
472a28ca 361
362 //Get users from wiki_entries
655b09ca 363 $st_entries = $DB->get_records_sql("SELECT DISTINCT u.id, u.id
364 FROM {user} u, {wiki_entries} e
365 WHERE e.wikiid = ? and
366 u.id = e.userid", array($wikiid));
472a28ca 367
368 //Add entries to pages
369 if ($st_entries) {
370 foreach ($st_entries as $st_entry) {
371 $st_pages[$st_entry->id] = $st_entry;
372 }
373 }
374
375 return $st_pages;
39fcb981 376}
377
472a28ca 378
39fcb981 379//////////////////////////////////////////////////////////////////////////////////////
8f0cd6ef 380/// Any other wiki functions go here. Each of them must have a name that
39fcb981 381/// starts with wiki_
382
e5cc530b 383/**
384 * Return the passed in string in Wiki name format.
385 * Remove any leading and trailing whitespace, capitalize all the words
386 * and then remove any internal whitespace.
387 *
388 * @param string $wikinane
389 * @return string
390 */
39fcb981 391function wiki_wiki_name($wikiname) {
39fcb981 392
393 if (wiki_is_wiki_name($wikiname)) {
394 return $wikiname;
395 }
396 else {
397 /// Create uppercase words and remove whitespace.
398 $wikiname = preg_replace("/(\w+)\s/", "$1", ucwords(trim($wikiname)));
399
400 /// Check again - there may only be one word.
401 if (wiki_is_wiki_name($wikiname)) {
402 return $wikiname;
403 }
404 /// If there is only one word, append default wiki name to it.
405 else {
406 return $wikiname.get_string('wikidefaultpagename', 'wiki');
407 }
408 }
409}
410
e5cc530b 411/**
412 * Check for correct wikiname syntax and return true or false.
413 *
414 * @param string $wikiname
415 * @return bool
416 */
39fcb981 417function wiki_is_wiki_name($wikiname) {
39fcb981 418
8f0cd6ef 419 /// If there are spaces between the words, incorrect format.
39fcb981 420 if (preg_match_all('/\w+/', $wikiname, $out) > 1) {
421 return false;
422 }
423 /// If there isn't more than one group of uppercase letters separated by
424 /// lowercase letters or '_', incorrect format.
425 else if (preg_match_all('/[A-Z]+[a-z_]+/', $wikiname, $out) > 1) {
426 return true;
427 }
8f0cd6ef 428 else {
39fcb981 429 return false;
430 }
431}
432
e5cc530b 433/**
434 * Determines the wiki's page name and returns it.
435 * @param object $wiki
436 * @return string
437 */
39fcb981 438function wiki_page_name(&$wiki) {
39fcb981 439 if (!empty($wiki->initialcontent)) {
440 $ppos = strrpos($wiki->initialcontent, '/');
441 if ($ppos === false) {
442 $pagename = $wiki->initialcontent;
443 }
444 else {
445 $pagename = substr($wiki->initialcontent, $ppos+1);
446 }
447 }
448 else if (!empty($wiki->pagename)) {
449 $pagename = $wiki->pagename;
450 }
451 else {
526efb55 452 $pagename = $wiki->name;
39fcb981 453 }
454 return $pagename;
455}
456
e5cc530b 457/**
458 * @global stdClass
459 * @param object $wiki
460 * @return string
461 */
39fcb981 462function wiki_content_dir(&$wiki) {
463/// Determines the wiki's default content directory (if there is one).
464 global $CFG;
465
466 if (!empty($wiki->initialcontent)) {
467 $ppos = strrpos($wiki->initialcontent, '/');
468 if ($ppos === false) {
469 $subdir = '';
470 }
471 else {
472 $subdir = substr($wiki->initialcontent, 0, $ppos+1);
473 }
474 $contentdir = $CFG->dataroot.'/'.$wiki->course.'/'.$subdir;
475 }
476 else {
477 $contentdir = false;
478 }
479 return $contentdir;
480}
481
e5cc530b 482/**
483 * Returns all wikis for the specified course and optionally of the specified type.
484 *
485 * @global object
486 * @param int $courseid
487 * @param string $wtype
488 * @return array
489 */
c513f599 490function wiki_get_course_wikis($courseid, $wtype='*') {
655b09ca 491 global $DB;
c513f599 492
655b09ca 493 $select = 'course = ?';
494 $params = array($courseid);
c513f599 495 if ($wtype != '*') {
655b09ca 496 $select .= ' AND wtype = ?';
497 $params[] = $wtype;
c513f599 498 }
655b09ca 499 return $DB->get_records_select('wiki', $select, $params, 'id');
c513f599 500}
501
e5cc530b 502/**
503 * Returns true if wiki already has wiki entries; otherwise false.
504 * @global object
505 * @param object $wiki
506 * @return bool
507 */
39fcb981 508function wiki_has_entries(&$wiki) {
655b09ca 509 global $DB;
39fcb981 510
655b09ca 511 return $DB->record_exists('wiki_entries', array('wikiid'=>$wiki->id));
39fcb981 512}
513
e5cc530b 514/**
515 * Returns an array with all wiki entries indexed by entry id; false if there are none.
516 * If the optional $byindex is specified, returns the entries indexed by that field.
517 * Valid values for $byindex are 'student', 'group'.
518 *
519 * @global stdClass
520 * @global object
521 * @param object $wiki
522 * @param string $byindex
523 */
39fcb981 524function wiki_get_entries(&$wiki, $byindex=NULL) {
655b09ca 525 global $CFG, $DB;
27978302 526
39fcb981 527 if ($byindex == 'student') {
655b09ca 528 return $DB->get_records('wiki_entries', array('wikiid'=>$wiki->id), '',
39fcb981 529 'userid,id,wikiid,course,groupid,pagename,timemodified');
530 }
531 else if ($byindex == 'group') {
655b09ca 532 return $DB->get_records('wiki_entries', array('wikiid'=>$wiki->id), '',
39fcb981 533 'groupid,id,wikiid,course,userid,pagename,timemodified');
534 }
535 else {
655b09ca 536 return $DB->get_records('wiki_entries', array('wikiid'=>$wiki->id));
39fcb981 537 }
538}
539
e5cc530b 540/**
541 * Returns the wiki entry according to the wiki type.
542 *
543 * Optionally, will return wiki entry for $userid student wiki, or
544 * $groupid group or teacher wiki.
545 * Creates one if it needs to and it can.
546 *
547 * @global object
548 * @param object $wiki By reference
549 * @param object $course By reference
550 * @param int $userid
551 * @param int $groupid
552 * @return object
553 */
c513f599 554function wiki_get_default_entry(&$wiki, &$course, $userid=0, $groupid=0) {
c513f599 555 global $USER;
b82fcee1 556 /// If there is a groupmode, get the user's group id.
27978302 557 $groupmode = groups_get_activity_groupmode($wiki);
b82fcee1 558 // if groups mode is in use and no group supplied, use the first one found
559 if ($groupmode && !$groupid) {
560 if(($mygroupids=mygroupid($course->id)) && count($mygroupids)>0) {
561 // Use first group. They ought to be able to change later
562 $groupid=$mygroupids[0];
563 } else {
564 // Whatever groups are in the course, pick one
2c386f82 565 $coursegroups = groups_get_all_groups($course->id);
b82fcee1 566 if(!$coursegroups || count($coursegroups)==0) {
4d6ba0f0 567 print_error('groupmodeerror', 'wiki');
f84d6a8d 568 }
b82fcee1 569 $unkeyed=array_values($coursegroups); // Make sure first item is index 0
570 $groupid=$unkeyed[0]->id;
571 }
572 }
573
c513f599 574 /// If the wiki entry doesn't exist, can this user create it?
575 if (($wiki_entry = wiki_get_entry($wiki, $course, $userid, $groupid)) === false) {
c513f599 576 if (wiki_can_add_entry($wiki, $USER, $course, $userid, $groupid)) {
577 wiki_add_entry($wiki, $course, $userid, $groupid);
578 if (($wiki_entry = wiki_get_entry($wiki, $course, $userid, $groupid)) === false) {
4d6ba0f0 579 print_error('cannotaddentry', 'wiki');
c513f599 580 }
581 }
582 }
fa22fd5f 583 //print_object($wiki_entry);
c513f599 584 return $wiki_entry;
585}
586
e5cc530b 587/**
588 * Returns the wiki entry according to the wiki type.
589 *
590 * Optionally, will return wiki entry for $userid student wiki, or
591 * $groupid group or teacher wiki.
592 * @global object
593 * @param object $wiki By reference
594 * @param object $course By reference
595 * @param int $userid
596 * @param int $groupid
597 * @return object
598 */
39fcb981 599function wiki_get_entry(&$wiki, &$course, $userid=0, $groupid=0) {
39fcb981 600 global $USER;
601
602 switch ($wiki->wtype) {
603 case 'student':
604 /// If a specific user was requested, return it, if allowed.
605 if ($userid and wiki_user_can_access_student_wiki($wiki, $userid, $course)) {
606 $wentry = wiki_get_student_entry($wiki, $userid);
607 }
608
609 /// If there is no entry for this user, check if this user is a teacher.
610 else if (!$wentry = wiki_get_student_entry($wiki, $USER->id)) {
ee3cc995 611/* if (wiki_is_teacher($wiki, $USER->id)) {
39fcb981 612 /// If this user is a teacher, return the first entry.
613 if ($wentries = wiki_get_entries($wiki)) {
614 $wentry = current($wentries);
615 }
616 }*/
617 }
618 break;
619
620 case 'group':
621 /// If there is a groupmode, get the user's group id.
27978302 622 $groupmode = groups_get_activity_groupmode($wiki);
745c1968 623 if($groupmode) {
624 if(!$groupid) {
625 if(($mygroupids=mygroupid($course->id)) && count($mygroupids)>0) {
626 // Use first group. They ought to be able to change later
627 $groupid=$mygroupids[0];
628 } else {
629 // Whatever groups are in the course, pick one
2c386f82 630 $coursegroups = groups_get_all_groups($course->id);
745c1968 631 if(!$coursegroups || count($coursegroups)==0) {
4d6ba0f0 632 print_error('groupmodeerror', 'wiki');
f84d6a8d 633 }
745c1968 634 $unkeyed=array_values($coursegroups); // Make sure first item is index 0
635 $groupid=$unkeyed[0]->id;
636 }
637 }
f84d6a8d 638
745c1968 639 //echo "groupid is in wiki_get_entry ".$groupid."<br />";
640 /// If a specific group was requested, return it, if allowed.
641 if ($groupid and wiki_user_can_access_group_wiki($wiki, $groupid, $course)) {
642 $wentry = wiki_get_group_entry($wiki, $groupid);
643 } else {
4d6ba0f0 644 print_error('cannotaccessgroup', 'wiki');
39fcb981 645 }
646 }
647 /// If mode is 'nogroups', then groupid is zero.
648 else {
649 $wentry = wiki_get_group_entry($wiki, 0);
650 }
651 break;
652
653 case 'teacher':
654 /// If there is a groupmode, get the user's group id.
655 if (groupmode($course, $wiki)) {
fa22fd5f 656 $mygroupids = mygroupid($course->id);//same here, default to the first one
657 $groupid = $groupid ? $groupid : $mygroupids[0]/*mygroupid($course->id)*/;
39fcb981 658 }
659
660 /// If a specific group was requested, return it, if allowed.
661 if (wiki_user_can_access_teacher_wiki($wiki, $groupid, $course)) {
662 $wentry = wiki_get_teacher_entry($wiki, $groupid);
663 }
664 break;
665 }
666 return $wentry;
667}
668
e5cc530b 669/**
670 * Returns the wiki entry for the wiki teacher type.
671 *
672 * @global object
673 * @param object $wiki
674 * @param int $groupid
675 * @return object
676 */
39fcb981 677function wiki_get_teacher_entry(&$wiki, $groupid=0) {
655b09ca 678 global $DB;
655b09ca 679 return $DB->get_record('wiki_entries', array('wikiid'=>$wiki->id, 'course'=>$wiki->course, 'groupid'=>$groupid));
39fcb981 680}
681
e5cc530b 682/**
683 * Returns the wiki entry for the given group.
684 *
685 * @global object
686 * @param object $wiki
687 * @param int $groupid
688 * @return object
689 */
39fcb981 690function wiki_get_group_entry(&$wiki, $groupid=null) {
655b09ca 691 global $DB;
655b09ca 692 return $DB->get_record('wiki_entries', array('wikiid'=>$wiki->id, 'groupid'=>$groupid));
39fcb981 693}
694
e5cc530b 695/**
696 * Returns the wiki entry for the given student.
697 *
698 * @global object
699 * @global object
700 * @param object $wiki
701 * @param int $userid
702 * @return object
703 */
39fcb981 704function wiki_get_student_entry(&$wiki, $userid=null) {
655b09ca 705 global $USER, $DB;
39fcb981 706
707 if (is_null($userid)) {
708 $userid = $USER->id;
709 }
655b09ca 710 return $DB->get_record('wiki_entries', array('wikiid'=>$wiki->id, 'userid'=>$userid));
39fcb981 711}
712
e5cc530b 713/**
714 * Returns a list of other wikis to display, depending on the type, group and user.
715 * Returns the key containing the currently selected entry as well.
716 *
717 * @global stdClass
718 * @global int
719 * @global object
720 * @param object $wiki
721 * @param object $user
722 * @param object $course
723 * @param int $currentid
724 * @return array
725 */
39fcb981 726function wiki_get_other_wikis(&$wiki, &$user, &$course, $currentid=0) {
655b09ca 727 global $CFG, $id, $DB;
39fcb981 728
729 $wikis = false;
730
27978302 731 $groupmode = groups_get_activity_groupmode($wiki);
39fcb981 732 $mygroupid = mygroupid($course->id);
ee3cc995 733 $isteacher = wiki_is_teacher($wiki, $user->id);
734 $isteacheredit = wiki_is_teacheredit($wiki, $user->id);
39fcb981 735
27978302 736 $groupingid = null;
737 $cm = new stdClass;
738 $cm->id = $wiki->cmid;
739 $cm->groupmode = $wiki->groupmode;
740 $cm->groupingid = $wiki->groupingid;
741 $cm->groupmembersonly = $wiki->groupmembersonly;
742 if (!empty($CFG->enablegroupings) && !empty($cm->groupingid)) {
743 $groupingid = $wiki->groupingid;
744 }
745
746
39fcb981 747 switch ($wiki->wtype) {
748
749 case 'student':
750 /// Get all the existing entries for this wiki.
751 $wiki_entries = wiki_get_entries($wiki, 'student');
27978302 752
753 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
655b09ca 754 $sql = "SELECT gm.userid FROM {groups_members} gm " .
755 "INNER JOIN {groupings_groups} gg ON gm.groupid = gg.groupid " .
756 "WHERE gg.groupingid = ? ";
27978302 757
655b09ca 758 $groupingmembers = $DB->get_records_sql($sql, array($wiki->groupingid));
27978302 759 }
760
222ac91b 761 if ($isteacher and (SITEID != $course->id)) {
39fcb981 762
763 /// If the user is an editing teacher, or a non-editing teacher not assigned to a group, show all student
764 /// wikis, regardless of creation.
222ac91b 765 if ((SITEID != $course->id) and ($isteacheredit or ($groupmode == NOGROUPS))) {
e2fc9a88 766 if ($students = get_users_by_capability(get_context_instance(CONTEXT_COURSE, $course->id), 'moodle/course:view', '', '', '', '', '', '', false)) {
39fcb981 767 /// Default pagename is dependent on the wiki settings.
768 $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
769
770 foreach ($students as $student) {
27978302 771 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid) && empty($groupingmembers[$student->id])) {
772 continue;
773 }
39fcb981 774 /// If this student already has an entry, use its pagename.
775 if ($wiki_entries[$student->id]) {
776 $pagename = $wiki_entries[$student->id]->pagename;
777 }
778 else {
779 $pagename = $defpagename;
780 }
781
d0b95287 782 $key = 'view.php?id='.$id.'&userid='.$student->id.'&page='.$pagename;
39fcb981 783 $wikis[$key] = fullname($student).':'.$pagename;
784 }
785 }
786 }
787 else if ($groupmode == SEPARATEGROUPS) {
fa22fd5f 788
ee3cc995 789 if ($students = wiki_get_students($wiki, $mygroupid)) {
39fcb981 790 $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
791 foreach ($students as $student) {
27978302 792 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid) && empty($groupingmembers[$student->id])) {
793 continue;
794 }
39fcb981 795 /// If this student already has an entry, use its pagename.
796 if ($wiki_entries[$student->id]) {
797 $pagename = $wiki_entries[$student->id]->pagename;
798 }
799 else {
800 $pagename = $defpagename;
801 }
802
d0b95287 803 $key = 'view.php?id='.$id.'&userid='.$student->id.'&page='.$pagename;
39fcb981 804 $wikis[$key] = fullname($student).':'.$pagename;
805 }
806 }
807 }
808 else if ($groupmode == VISIBLEGROUPS) {
8f0cd6ef 809 /// Get all students in your group.
ee3cc995 810 if ($students = wiki_get_students($wiki, $mygroupid)) {
39fcb981 811 $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
812 foreach ($students as $student) {
27978302 813 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid) && empty($groupingmembers[$student->id])) {
814 continue;
815 }
39fcb981 816 /// If this student already has an entry, use its pagename.
817 if ($wiki_entries[$student->id]) {
818 $pagename = $wiki_entries[$student->id]->pagename;
819 }
820 else {
821 $pagename = $defpagename;
822 }
d0b95287 823 $key = 'view.php?id='.$id.'&userid='.$student->id.'&page='.$pagename;
39fcb981 824 $wikis[$key] = fullname($student).':'.$pagename;
825 }
826 }
827 /// Get all student wikis created, regardless of group.
27978302 828 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
829 $sql = 'SELECT w.id, w.userid, w.pagename, u.firstname, u.lastname '
655b09ca 830 .' FROM {wiki_entries} w '
831 .' INNER JOIN {user} u ON w.userid = u.id '
832 .' INNER JOIN {groups_members} gm ON gm.userid = u.id '
833 .' INNER JOIN {groupings_groups} gg ON gm.groupid = gg.groupid '
834 .' WHERE w.wikiid = ? AND gg.groupingid = ?'
27978302 835 .' ORDER BY w.id';
655b09ca 836 $params = array($wiki->id, $wiki->groupingid);
27978302 837 } else {
838 $sql = 'SELECT w.id, w.userid, w.pagename, u.firstname, u.lastname '
655b09ca 839 .' FROM {wiki_entries} w, {user} u '
840 .' WHERE w.wikiid = ? AND u.id = w.userid '
27978302 841 .' ORDER BY w.id';
655b09ca 842 $params = array($wiki->id);
27978302 843 }
655b09ca 844 $wiki_entries = $DB->get_records_sql($sql, $params);
39fcb981 845 $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
846 foreach ($wiki_entries as $wiki_entry) {
d0b95287 847 $key = 'view.php?id='.$id.'&userid='.$wiki_entry->userid.'&page='.$wiki_entry->pagename;
39fcb981 848 $wikis[$key] = fullname($wiki_entry).':'.$wiki_entry->pagename;
849 if ($currentid == $wiki_entry->id) {
850 $wikis['selected'] = $key;
851 }
852 }
8f0cd6ef 853 }
39fcb981 854 }
855 else {
856 /// A user can see other student wikis if they are a member of the same
857 /// group (for separate groups) or there are visible groups, or if this is
858 /// a site-level wiki, and they are an administrator.
1d126f4f 859 if (($groupmode == VISIBLEGROUPS) or wiki_is_teacheredit($wiki)) {
39fcb981 860 $viewall = true;
861 }
862 else if ($groupmode == SEPARATEGROUPS) {
863 $viewall = mygroupid($course->id);
864 }
865 else {
866 $viewall = false;
867 }
868
869 if ($viewall !== false) {
27978302 870 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
871 $sql = 'SELECT w.id, w.userid, w.pagename, u.firstname, u.lastname '
655b09ca 872 .' FROM {wiki_entries} w '
873 .' INNER JOIN {user} u ON w.userid = u.id '
874 .' INNER JOIN {groups_members} gm ON gm.userid = u.id '
875 .' INNER JOIN {groupings_groups} gg ON gm.groupid = gg.groupid '
876 .' WHERE w.wikiid = ? AND gg.groupingid = ?'
27978302 877 .' ORDER BY w.id';
655b09ca 878 $params = array($wiki->id, $wiki->groupingid);
27978302 879 } else {
880 $sql = 'SELECT w.id, w.userid, w.pagename, u.firstname, u.lastname '
655b09ca 881 .' FROM {wiki_entries} w, {user} u '
882 .' WHERE w.wikiid = ? AND u.id = w.userid '
27978302 883 .' ORDER BY w.id';
655b09ca 884 $params = array($wiki->id);
27978302 885 }
655b09ca 886 $wiki_entries = $DB->get_records_sql($sql, $params);
39fcb981 887 $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
888 foreach ($wiki_entries as $wiki_entry) {
27978302 889 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid) && empty($groupingmembers[$wiki_entry->userid])) {
890 continue;
891 }
892
2c386f82 893 if (($viewall === true) or groups_is_member($viewall, $wiki_entry->userid)) {
d0b95287 894 $key = 'view.php?id='.$id.'&userid='.$wiki_entry->userid.'&page='.$wiki_entry->pagename;
39fcb981 895 $wikis[$key] = fullname($wiki_entry).':'.$wiki_entry->pagename;
896 if ($currentid == $wiki_entry->id) {
897 $wikis['selected'] = $key;
898 }
899 }
900 }
901 }
902 }
903 break;
904
905 case 'group':
906 /// If the user is an editing teacher, or a non-editing teacher not assigned to a group, show all group
907 /// wikis, regardless of creation.
f84d6a8d 908
fa22fd5f 909 /// If user is a member of multiple groups, need to show current group etc?
39fcb981 910
911 /// Get all the existing entries for this wiki.
912 $wiki_entries = wiki_get_entries($wiki, 'group');
27978302 913
39fcb981 914 if ($groupmode and ($isteacheredit or ($isteacher and !$mygroupid))) {
27978302 915 if ($groups = groups_get_all_groups($course->id, null, $groupingid)) {
39fcb981 916 $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
917 foreach ($groups as $group) {
918
919 /// If this group already has an entry, use its pagename.
920 if (isset($wiki_entries[$group->id])) {
921 $pagename = $wiki_entries[$group->id]->pagename;
922 }
923 else {
924 $pagename = $defpagename;
925 }
926
d0b95287 927 $key = 'view.php?id='.$id.($group->id?"&groupid=".$group->id:"").'&page='.$pagename;
39fcb981 928 $wikis[$key] = $group->name.':'.$pagename;
929 }
930 }
931 }
fa22fd5f 932 //if a studnet with multiple groups in SPG
933 else if ($groupmode == SEPARATEGROUPS){
27978302 934 if ($groups = groups_get_all_groups($course->id, $user->id, $groupingid)){
fa22fd5f 935
936 $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
937 foreach ($groups as $group) {
938 /// If this group already has an entry, use its pagename.
939 if (isset($wiki_entries[$group->id])) {
940 $pagename = $wiki_entries[$group->id]->pagename;
941 }
942 else {
943 $pagename = $defpagename;
944 }
945 $key = 'view.php?id='.$id.($group->id?"&groupid=".$group->id:"").'&page='.$pagename;
946 $wikis[$key] = $group->name.':'.$pagename;
947 }
948
949 }
950
951 }
39fcb981 952 /// A user can see other group wikis if there are visible groups.
953 else if ($groupmode == VISIBLEGROUPS) {
27978302 954 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
955 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
655b09ca 956 .' FROM {wiki_entries} w '
957 .' INNER JOIN {groups} g ON g.id = w.groupid '
958 .' INNER JOIN {groupings_groups} gg ON g.id = gg.groupid '
959 .' WHERE w.wikiid = ? AND gg.groupingid = ?'
27978302 960 .' ORDER BY w.groupid';
655b09ca 961 $params = array($wiki->id, $wiki->groupingid);
27978302 962 } else {
963 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
655b09ca 964 .' FROM {wiki_entries} w, {groups} g '
965 .' WHERE w.wikiid = ? AND g.id = w.groupid '
27978302 966 .' ORDER BY w.groupid';
655b09ca 967 $params = array($wiki->id);
27978302 968 }
655b09ca 969 $wiki_entries = $DB->get_records_sql($sql, $params);
39fcb981 970 $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
971 foreach ($wiki_entries as $wiki_entry) {
d0b95287 972 $key = 'view.php?id='.$id.($wiki_entry->groupid?"&groupid=".$wiki_entry->groupid:"").'&page='.$wiki_entry->pagename;
39fcb981 973 $wikis[$key] = $wiki_entry->gname.':'.$wiki_entry->pagename;
974 if ($currentid == $wiki_entry->id) {
975 $wikis['selected'] = $key;
976 }
977 }
978 }
979 break;
980
981 case 'teacher':
982 if ($isteacher) {
983 /// If the user is an editing teacher, or a non-editing teacher not assigned to a group, show all
984 /// teacher wikis, regardless of creation.
985 if ($groupmode and ($isteacheredit or ($isteacher and !$mygroupid))) {
27978302 986 if ($groups = groups_get_all_groups($course->id, null, $groupingid)) {
39fcb981 987 $defpagename = empty($wiki->pagename) ? get_string('wikidefaultpagename', 'wiki') : $wiki->pagename;
39fcb981 988 foreach ($groups as $group) {
989 /// If this group already has an entry, use its pagename.
990 if ($wiki_entries[$group->id]) {
991 $pagename = $wiki_entries[$group->id]->pagename;
992 }
993 else {
994 $pagename = $defpagename;
995 }
996
d0b95287 997 $key = 'view.php?id='.$id.($group->id?"&groupid=".$group->id:"").'&page='.$pagename;
39fcb981 998 $wikis[$key] = $group->name.':'.$pagename;
999 }
1000 }
1001 }
1002 /// A teacher can see all other group teacher wikis.
1003 else if ($groupmode) {
27978302 1004 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
1005 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
655b09ca 1006 .' FROM {wiki_entries} w '
1007 .' INNER JOIN {groups} g ON g.id = w.groupid '
1008 .' INNER JOIN {groupings_groups} gg ON g.id = gg.groupid '
1009 .' WHERE w.wikiid = ? AND gg.groupingid = ?'
27978302 1010 .' ORDER BY w.groupid';
655b09ca 1011 $params = array($wiki->id, $wiki->groupingid);
27978302 1012 } else {
39fcb981 1013 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
655b09ca 1014 .' FROM {wiki_entries} w, {groups} g '
1015 .' WHERE w.wikiid = ? AND g.id = w.groupid '
39fcb981 1016 .' ORDER BY w.groupid';
655b09ca 1017 $params = array($wiki->id);
27978302 1018 }
655b09ca 1019 $wiki_entries = $DB->get_records_sql($sql, $params);
39fcb981 1020 $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
1021 foreach ($wiki_entries as $wiki_entry) {
d0b95287 1022 $key = 'view.php?id='.$id.($wiki_entry->groupid?"&groupid=".$wiki_entry->groupid:"").'&page='.$wiki_entry->pagename;
39fcb981 1023 $wikis[$key] = $wiki_entry->gname.':'.$wiki_entry->pagename;
1024 if ($currentid == $wiki_entry->id) {
1025 $wikis['selected'] = $key;
1026 }
1027 }
1028 }
1029 }
1030 else {
1031 /// A user can see other teacher wikis if they are a teacher, a member of the same
1032 /// group (for separate groups) or there are visible groups.
1033 if ($groupmode == VISIBLEGROUPS) {
1034 $viewall = true;
1035 }
1036 else if ($groupmode == SEPARATEGROUPS) {
1037 $viewall = $mygroupid;
1038 }
1039 else {
1040 $viewall = false;
1041 }
1042 if ($viewall !== false) {
27978302 1043 if (!empty($CFG->enablegroupings) && !empty($wiki->groupingid)) {
1044 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
655b09ca 1045 .' FROM {wiki_entries} w '
1046 .' INNER JOIN {groups} g ON g.id = w.groupid '
1047 .' INNER JOIN {groupings_groups} gg ON g.id = gg.groupid '
1048 .' WHERE w.wikiid = ? AND gg.groupingid = ?'
27978302 1049 .' ORDER BY w.groupid';
655b09ca 1050 $params = array($wiki->id, $wiki->groupingid);
27978302 1051 } else {
1052 $sql = 'SELECT w.id, w.groupid, w.pagename, g.name as gname '
655b09ca 1053 .' FROM {wiki_entries} w, {groups} g '
1054 .' WHERE w.wikiid = ? AND g.id = w.groupid '
27978302 1055 .' ORDER BY w.groupid';
655b09ca 1056 $params = array($wiki->id);
27978302 1057 }
655b09ca 1058 $wiki_entries = $DB->get_records_sql($sql, $params);
39fcb981 1059 $wiki_entries=is_array($wiki_entries)?$wiki_entries:array();
fa22fd5f 1060
1061
39fcb981 1062 foreach ($wiki_entries as $wiki_entry) {
fa22fd5f 1063 if (($viewall === true) or @in_array($wiki_entry->groupid, $viewall)/*$viewall == $wiki_entry->groupid*/) {
1064 $key = 'view.php?id='.$id.($wiki_entry->groupid?"&groupid=".$wiki_entry->groupid:"").'&page='.$wiki_entry->pagename;
39fcb981 1065 $wikis[$key] = $wiki_entry->gname.':'.$wiki_entry->pagename;
1066 if ($currentid == $wiki_entry->id) {
1067 $wikis['selected'] = $key;
1068 }
1069 }
1070 }
1071 }
1072 }
1073 break;
1074 }
27978302 1075
39fcb981 1076 return $wikis;
1077}
1078
e5cc530b 1079/**
1080 * Adds a new wiki entry of the specified type, unless already entered.
1081 *
1082 * No checking is done here. It is assumed that the caller has the correct
1083 * privileges to add this entry.
1084 *
1085 * @global object
1086 * @global object
1087 * @param object $wiki
1088 * @param object $course
1089 * @param int $userid
1090 * @param int $groupid
1091 * @return bool
1092 */
39fcb981 1093function wiki_add_entry(&$wiki, &$course, $userid=0, $groupid=0) {
655b09ca 1094 global $USER, $DB;
39fcb981 1095
1096 /// If this wiki already has a wiki_type entry, return false.
1097 if (wiki_get_entry($wiki, $course, $userid, $groupid) !== false) {
1098 return false;
1099 }
1100
ee3cc995 1101 $wiki_entry = new Object();
1102
39fcb981 1103 switch ($wiki->wtype) {
1104
1105 case 'student':
1106 $wiki_entry->wikiid = $wiki->id;
1107 $wiki_entry->userid = $userid ? $userid : $USER->id;
1108 $wiki_entry->pagename = wiki_page_name($wiki);
1109 $wiki_entry->timemodified = time();
1110 break;
1111
1112 case 'group':
1113 /// Get the groupmode. It's been added to the wiki object.
27978302 1114 $groupmode = groups_get_activity_groupmode($wiki);
39fcb981 1115
fa22fd5f 1116 ///give the first groupid by default and try
1117 $mygroups = mygroupid($course->id);
1118
39fcb981 1119 /// If there is a groupmode, get the group id.
1120 if ($groupmode) {
fa22fd5f 1121 $groupid = $groupid ? $groupid : $mygroups[0]/*mygroupid($course->id)*/;
39fcb981 1122 }
1123 /// If mode is 'nogroups', then groupid is zero.
1124 else {
1125 $groupid = 0;
1126 }
1127 $wiki_entry->wikiid = $wiki->id;
1128 $wiki_entry->groupid = $groupid;
1129 $wiki_entry->pagename = wiki_page_name($wiki);
1130 $wiki_entry->timemodified = time();
f84d6a8d 1131
39fcb981 1132 break;
1133
1134 case 'teacher':
1135 /// Get the groupmode. It's been added to the wiki object.
27978302 1136 $groupmode = groups_get_activity_groupmode($wiki);
39fcb981 1137
1138 /// If there is a groupmode, get the user's group id.
1139 if ($groupmode and $groupid == 0) {
fa22fd5f 1140 $mygroupid = mygroupid($course->id);
1141 $groupid = $mygroupid[0]/*mygroupid($course->id)*/;
39fcb981 1142 }
1143
1144 $wiki_entry->wikiid = $wiki->id;
1145 $wiki_entry->course = $wiki->course;
1146 $wiki_entry->groupid = $groupid;
1147 $wiki_entry->pagename = wiki_page_name($wiki);
1148 $wiki_entry->timemodified = time();
1149 break;
1150 }
655b09ca 1151 $wiki_entry->pagename = $wiki_entry->pagename;
e61d4b39 1152
655b09ca 1153 return $DB->insert_record("wiki_entries", $wiki_entry, true);
39fcb981 1154}
1155
e5cc530b 1156/**
1157 * Returns true or false if the user can add a wiki entry for this wiki.
1158 *
1159 * @param object $wiki By reference
1160 * @param object $user By reference
1161 * @param object $course By reference
1162 * @param int $userid
1163 * @param int $groupid
1164 * @return bool
1165 */
39fcb981 1166function wiki_can_add_entry(&$wiki, &$user, &$course, $userid=0, $groupid=0) {
39fcb981 1167 /// Get the groupmode. It's been added to the wiki object.
27978302 1168 $groupmode = groups_get_activity_groupmode($wiki);
39fcb981 1169 $mygroupid = mygroupid($course->id);
39fcb981 1170
1171 switch ($wiki->wtype) {
1172
1173 case 'student':
1174/// A student can create their own wiki, if they are a member of that course.
1175/// A user can create their own wiki at the site level.
1176 if ($userid == 0) {
ee3cc995 1177 return (wiki_is_student($wiki, $user->id) or wiki_is_student($wiki, $user->id));
39fcb981 1178 }
1179/// An editing teacher can create any student wiki, or
1180/// a non-editing teacher, if not assigned to a group can create any student wiki, or if assigned to a group can
1181/// create any student wiki in their group.
1182 else {
ee3cc995 1183 return ((($userid == $user->id) and wiki_is_student($wiki, $user->id)) or wiki_is_teacheredit($wiki) or
2c386f82 1184 (wiki_is_teacher($wiki) and (!$groupmode or $mygroupid == 0 or (groups_is_member($mygroupid, $userid)))));
39fcb981 1185 }
1186 break;
1187
1188 case 'group':
1189 /// If mode is 'nogroups', then all participants can add wikis.
b82fcee1 1190 if (wiki_is_teacheredit($wiki, $user->id)) {
f84d6a8d 1191 return true;
b82fcee1 1192 }
f84d6a8d 1193
39fcb981 1194 if (!$groupmode) {
ee3cc995 1195 return (wiki_is_student($wiki, $user->id) or wiki_is_teacher($wiki, $user->id));
39fcb981 1196 }
1197 /// If not requesting a group, must be a member of a group.
1198 else if ($groupid == 0) {
8f0cd6ef 1199 return ($mygroupid != 0);
39fcb981 1200 }
1201 /// If requesting a group, must be an editing teacher, a non-editing teacher with no assigned group,
fa22fd5f 1202 /// or a non-editing teacher requesting their group. or a student in group, but wiki is empty.
39fcb981 1203 else {
ee3cc995 1204 return (wiki_is_teacheredit($wiki) or
1205 (wiki_is_teacher($wiki) and ($mygroupid == 0 or @in_array($groupid, $mygroupid))) or
1206 (wiki_is_student($wiki, $user->id) and @in_array($groupid, $mygroupid))
fa22fd5f 1207 );
39fcb981 1208 }
1209 break;
1210
1211 case 'teacher':
1212 /// If mode is 'nogroups', then all teachers can add wikis.
1213 if (!$groupmode) {
1d126f4f 1214 return wiki_is_teacher($wiki, $user->id);
39fcb981 1215 }
1216 /// If not requesting a group, must be a member of a group.
1217 else if ($groupid == 0) {
ee3cc995 1218 return ($mygroupid != 0 and wiki_is_teacher($wiki));
39fcb981 1219 }
8f0cd6ef 1220 /// If there is a group mode, non-editing teachers with an assigned group, can only create wikis
39fcb981 1221 /// in their group. Non-editing teachers with no assigned group and editing teachers can create any wiki.
1222 else {
ee3cc995 1223 return (wiki_is_teacheredit($wiki) or
1224 (wiki_is_teacher($wiki) and ($mygroupid == 0 or @in_array($groupid, $mygroupid))));
39fcb981 1225 }
1226 break;
1227 }
1228
1229 return false;
1230}
1231
e5cc530b 1232/**
1233 * Returns true or false if the user can edit this wiki entry.
1234 *
1235 * @param object $wiki_entry by reference
1236 * @param object $wiki by reference
1237 * @param object $user by reference
1238 * @param object $course by reference
1239 * @return bool
1240 */
39fcb981 1241function wiki_can_edit_entry(&$wiki_entry, &$wiki, &$user, &$course) {
39fcb981 1242
1243 $can_edit = false;
27978302 1244 $groupmode = groups_get_activity_groupmode($wiki);
39fcb981 1245 $mygroupid = mygroupid($course->id);
39fcb981 1246
8f0cd6ef 1247 /// Editing teacher's and admins can edit all wikis, non-editing teachers can edit wikis in their groups,
39fcb981 1248 /// or all wikis if group mode is 'no groups' or they don't belong to a group.
1d126f4f 1249 if (wiki_is_teacheredit($wiki, $user->id) or
ee3cc995 1250 ((!$groupmode or $mygroupid == 0) and wiki_is_teacher($wiki, $user->id))) {
39fcb981 1251 $can_edit = true;
1252 }
1253 else {
1254 switch ($wiki->wtype) {
1255
1256 /// Only a teacher or the owner of a student wiki can edit it.
1257 case 'student':
1258 $can_edit = (($user->id == $wiki_entry->userid) or
ee3cc995 1259 ($groupmode and wiki_is_teacher($wiki, $user->id) and
2c386f82 1260 groups_is_member($mygroupid, $wiki_entry->userid)));
39fcb981 1261 break;
1262
1263 case 'group':
1264 /// If there is a groupmode, determine the user's group status.
1265 if ($groupmode) {
1266 /// If the user is a member of the wiki group, they can edit the wiki.
2c386f82 1267 $can_edit = groups_is_member($wiki_entry->groupid, $user->id);
39fcb981 1268 }
1269 /// If mode is 'nogroups', then all participants can edit the wiki.
1270 else {
ee3cc995 1271 $can_edit = (wiki_is_student($wiki, $user->id) or wiki_is_teacher($wiki, $user->id));
39fcb981 1272 }
1273 break;
1274
1275 case 'teacher':
1276 /// If there is a groupmode, determine the user's group status.
1277 if ($groupmode) {
1278 /// If the user is a member of the wiki group, they can edit the wiki.
2c386f82 1279 $can_edit = (wiki_is_teacher($wiki, $user->id) and groups_is_member($wiki_entry->groupid, $user->id));
39fcb981 1280 }
1281 else {
1d126f4f 1282 $can_edit = wiki_is_teacher($wiki, $user->id);
39fcb981 1283 }
1284 break;
1285 }
1286 }
39fcb981 1287 return $can_edit;
1288}
1289
e5cc530b 1290/**
1291 * @global object
1292 * @param object $wiki by reference
1293 * @param int $userid
1294 * @param object $course
1295 * @return bool
1296 */
39fcb981 1297function wiki_user_can_access_student_wiki(&$wiki, $userid, &$course) {
1298 global $USER;
1299
1300 /// Get the groupmode. It's been added to the wiki object.
27978302 1301 $groupmode = groups_get_activity_groupmode($wiki);
39fcb981 1302 $usersgroup = mygroupid($course->id);
ee3cc995 1303 $isteacher = wiki_is_teacher($wiki, $USER->id);
39fcb981 1304
1305 /// If this user is allowed to access this wiki then return TRUE.
1306 /// *** THIS COULD BE A PROBLEM, IF STUDENTS COULD EVER BE PART OF MORE THAN ONE GROUP ***
1307 /// A user can access a student wiki, if:
1308 /// - it is their wiki,
1309 /// - group mode is VISIBLEGROUPS,
1310 /// - group mode is SEPARATEGROUPS, and the user is a member of the requested user's group,
1311 /// - they are an editing teacher or administrator,
1312 /// - they are a non-editing teacher not assigned to a specific group,
1313 /// - they are a non-editing teacher and group mode is NOGROUPS.
1314 /// - they are an administrator (mostly for site-level wikis).
1315 if (($userid and ($USER->id == $userid)) or ($groupmode == VISIBLEGROUPS) or
2c386f82 1316 (($groupmode == SEPARATEGROUPS) and groups_is_member($usersgroup, $userid)) or
ee3cc995 1317 (wiki_is_teacheredit($wiki, $USER->id)) or
1d126f4f 1318 (wiki_is_teacher($wiki, $USER->id) and (!$usersgroup or $groupmode == NOGROUPS))) {
39fcb981 1319 $can_access = true;
1320 }
1321 else {
1322 $can_access = false;
1323 }
1324 return $can_access;
1325}
1326
e5cc530b 1327/**
1328 * @global object
1329 * @param object $wiki by reference
1330 * @param int $groupid
1331 * @param object $course
1332 * @return bool
1333 */
39fcb981 1334function wiki_user_can_access_group_wiki(&$wiki, $groupid, &$course) {
1335 global $USER;
1336
1337 /// Get the groupmode. It's been added to the wiki object.
27978302 1338 $groupmode = groups_get_activity_groupmode($wiki);
39fcb981 1339 $usersgroup = mygroupid($course->id);
ee3cc995 1340 $isteacher = wiki_is_teacher($wiki, $USER->id);
39fcb981 1341
1342 /// A user can access a group wiki, if:
1343 /// - group mode is NOGROUPS,
1344 /// - group mode is VISIBLEGROUPS,
1345 /// - group mode is SEPARATEGROUPS, and they are a member of the requested group,
1346 /// - they are an editing teacher or administrator,
1347 /// - they are a non-editing teacher not assigned to a specific group.
8f0cd6ef 1348 if (($groupmode == NOGROUPS) or ($groupmode == VISIBLEGROUPS) or
fa22fd5f 1349 (($groupmode == SEPARATEGROUPS) and @in_array($groupid, $usersgroup)/*($usersgroup == $groupid)*/) or
ee3cc995 1350 (wiki_is_teacheredit($wiki, $USER->id)) or
1351 (wiki_is_teacher($wiki, $USER->id) and !$usersgroup)) {
39fcb981 1352 $can_access = true;
1353 }
1354 else {
1355 $can_access = false;
1356 }
1357 return $can_access;
1358}
1359
e5cc530b 1360/**
1361 * @global object
1362 * @param object $wiki by reference
1363 * @param int $groupid
1364 * @param object $course by reference
1365 * @return bool
1366 */
39fcb981 1367function wiki_user_can_access_teacher_wiki(&$wiki, $groupid, &$course) {
1368 global $USER;
1369
1370 /// Get the groupmode. It's been added to the wiki object.
27978302 1371 $groupmode = groups_get_activity_groupmode($wiki);
39fcb981 1372
1373 /// A user can access a teacher wiki, if:
1374 /// - group mode is NOGROUPS,
1375 /// - group mode is VISIBLEGROUPS,
1376 /// - group mode is SEPARATEGROUPS, and they are a member of the requested group,
1377 /// - they are a teacher or administrator,
8f0cd6ef 1378 if (($groupmode == NOGROUPS) or ($groupmode == VISIBLEGROUPS) or
fa22fd5f 1379 (($groupmode == SEPARATEGROUPS) and (@in_array($groupid, mygroupid($course->id))/*mygroupid($course->id) == $groupid*/)) or
ee3cc995 1380 (wiki_is_teacher($wiki, $USER->id))){
39fcb981 1381 $can_access = true;
1382 }
1383 else {
1384 $can_access = false;
1385 }
1386 return $can_access;
1387}
1388
e5cc530b 1389/**
1390 * @global object
1391 * @param object $wiki_entry by reference
1392 * @return string
1393 */
39fcb981 1394function wiki_get_owner(&$wiki_entry) {
655b09ca 1395 global $DB;
1396
39fcb981 1397 if ($wiki_entry->userid > 0) {
655b09ca 1398 $user = $DB->get_record('user', array('id'=>$wiki_entry->userid));
39fcb981 1399 $owner = fullname($user);
1400 }
1401 else if ($wiki_entry->groupid > 0) {
f3f7610c 1402 $owner = groups_get_group_name($wiki_entry->groupid); //TODO:check.
39fcb981 1403 }
1404 else if ($wiki_entry->course > 0) {
655b09ca 1405 $course = $DB->get_record('course', array('id'=>$wiki_entry->course));
39fcb981 1406 $owner = $course->shortname;
1407 }
1408 else {
a9de0242 1409 $owner = '- '.get_string("ownerunknown","wiki").' -';
39fcb981 1410 }
1411 return $owner;
1412}
1413
e5cc530b 1414/**
1415 * @todo Add Group and User !!!
1416 *
1417 * @global stdClass
1418 * @param int $cmid
1419 * @param string $search
1420 * @param int $userid
1421 * @param int $groupid
1422 * @param bool $return
1423 * @return string
1424 */
39fcb981 1425function wiki_print_search_form($cmid, $search="", $userid, $groupid, $return=false) {
1426 global $CFG;
1427 # TODO: Add Group and User !!!
b7dc2256 1428 $output = "<form id=\"search\" action=\"$CFG->wwwroot/mod/wiki/view.php\">";
beae1797 1429 $output .="<fieldset class='invisiblefieldset'>";
1430 $output .= "<span style='font-size:0.6em;'>";
a9ef4a63 1431 $output .= "<input value=\"".get_string("searchwiki", "wiki").":\" type=\"submit\" />";
1432 $output .= "<input name=\"id\" type=\"hidden\" value=\"$cmid\" />";
1433 $output = $output.($groupid?"<input name=\"groupid\" type=\"hidden\" value=\"$groupid\" />":"");
1434 $output = $output.($userid?"<input name=\"userid\" type=\"hidden\" value=\"$userid\" />":"");
4c2740fc 1435 $output .= "<input name=\"q\" type=\"text\" size=\"20\" value=\"".s($search)."\" />".' ';
beae1797 1436 $output .= "</span>";
a9ef4a63 1437 $output .= "<input name=\"page\" type=\"hidden\" value=\"SearchPages\" />";
beae1797 1438 $output .= "</fieldset>";
39fcb981 1439 $output .= "</form>";
1440
1441 if ($return) {
1442 return $output;
1443 }
1444 echo $output;
1445}
1446
e5cc530b 1447/**
1448 * Prints a link-list of special wiki-pages
1449 *
1450 * @global object
1451 * @global string
1452 * @param int $cmid
1453 * @param bool $binary
1454 * @param bool $return
1455 */
39fcb981 1456function wiki_print_wikilinks_block($cmid, $binary=false, $return=false) {
928c9b4a 1457 global $CFG, $ewiki_title, $OUTPUT;
39fcb981 1458
1459 $links=array();
1460
f80b0733 1461 $links["SiteMap"]=get_string("sitemap", "wiki");
39fcb981 1462 $links["PageIndex"]=get_string("pageindex", "wiki");
1463 $links["NewestPages"]=get_string("newestpages", "wiki");
1464 $links["MostVisitedPages"]=get_string("mostvisitedpages", "wiki");
1465 $links["MostOftenChangedPages"]=get_string("mostoftenchangedpages", "wiki");
1466 $links["UpdatedPages"]=get_string("updatedpages", "wiki");
1467 $links["OrphanedPages"]=get_string("orphanedpages", "wiki");
1468 $links["WantedPages"]=get_string("wantedpages", "wiki");
a9de0242 1469 $links["WikiExport"]=get_string("wikiexport", "wiki");
39fcb981 1470 if($binary) {
1471 $links["FileDownload"]=get_string("filedownload", "wiki");
1472 }
928c9b4a 1473
1474 $name = null;
1475 if (preg_match('/([a-zA-Z0-9\-_]*)=$/', EWIKI_SCRIPT, $matches)) {
1476 $name = $matches[1];
1477 }
1478
7b1f2c82 1479 $select = html_select::make_popup_form(EWIKI_SCRIPT, $name, $links, 'wikilinks');
928c9b4a 1480 $select->nothinglabel = get_string("choosewikilinks", "wiki");
1481 echo $OUTPUT->select($select);
39fcb981 1482}
1483
e5cc530b 1484/**
1485 * Displays actions which can be performed on the page
1486 * @param int $cmit
1487 * @param array $specialpages
1488 * @param array $page
1489 * @param string $action
1490 * @param bool $binary
1491 * @param bool $canedit
1492 */
087fef3e 1493function wiki_print_page_actions($cmid, $specialpages, $page, $action, $binary=false, $canedit=true) {
39fcb981 1494
1495 $page=array();
1496
1497 // Edit this Page
1498 if (in_array($action, array("edit", "links", "info", "attachments"))) {
8f0cd6ef 1499 $page["view/$page"]=get_string("viewpage","wiki");
39fcb981 1500 }
087fef3e 1501 if ($canedit && !in_array($page, $specialpages) && $action != "edit") {
1502 $page["edit/$page"]=get_string("editthispage","wiki");
39fcb981 1503 }
1504 if ($action != "links") {
087fef3e 1505 $page["links/$page"]=get_string("backlinks","wiki");
39fcb981 1506 }
087fef3e 1507 if ($canedit && !in_array($page, $specialpages) && $action!="info") {
1508 $page["info/$page"]=get_string("pageinfo","wiki");
39fcb981 1509 }
087fef3e 1510 if($canedit && $binary && !in_array($page, $specialpages) && $action != "attachments") {
1511 $page["attachments/$page"]=get_string("attachments","wiki");
39fcb981 1512 }
928c9b4a 1513
1514 $name = null;
1515 if (preg_match('/([a-zA-Z0-9\-_]*)=$/', EWIKI_SCRIPT, $matches)) {
1516 $name = $matches[1];
1517 }
39fcb981 1518
7b1f2c82 1519 $select = html_select::make_popup_form(EWIKI_SCRIPT, $name, $page, 'wikiactions');
928c9b4a 1520 $select->nothinglabel = get_string("action", "wiki");
1521 echo $OUTPUT->select($select);
39fcb981 1522}
1523
e5cc530b 1524/**
1525 * Displays actions which can be performed on the page
1526 *
1527 * @param object $wiki
1528 * @param int $cmid
1529 * @param int $userid
1530 * @param int $groupid
1531 * @param object $page
1532 * @param bool $noeditor
1533 * @param object $course
1534 */
087fef3e 1535function wiki_print_administration_actions($wiki, $cmid, $userid, $groupid, $page, $noeditor, $course) {
928c9b4a 1536 global $OUTPUT;
f84d6a8d 1537 /// Create the URL
39fcb981 1538 $ewscript = 'admin.php?id='.$cmid;
928c9b4a 1539 if (isset($userid) && $userid!=0) $ewscript .= '&userid='.$userid;
1540 if (isset($groupid) && $groupid!=0) $ewscript .= '&groupid='.$groupid;
1541 if (isset($page)) $ewscript .= '&page='.$page;
39fcb981 1542
c513f599 1543
1544 /// Build that action array according to wiki flags.
1545 $action = array();
ee3cc995 1546 $isteacher = wiki_is_teacher($wiki);
c513f599 1547
1548 if ($wiki->setpageflags or $isteacher) {
1549 $action['setpageflags'] = get_string('setpageflags', 'wiki');
1550 }
1551 if ($wiki->removepages or $isteacher) {
1552 $action['removepages'] = get_string('removepages', 'wiki');
1553 }
1554 if ($wiki->strippages or $isteacher) {
1555 $action['strippages'] = get_string('strippages', 'wiki');
1556 }
1557 if ($wiki->revertchanges or $isteacher) {
1558 $action['revertpages'] = get_string('revertpages', 'wiki');
1559 }
1560
39fcb981 1561 if($noeditor) {
1562 $action["checklinks"]=get_string("checklinks", "wiki");
1563 }
7b1f2c82 1564 $select = html_select::make_popup_form($ewscript, 'action', $action, 'wikiadministration');
928c9b4a 1565 $select->nothinglabel = get_string("chooseadministration", "wiki");
1566 echo $OUTPUT->select($select);
39fcb981 1567}
1568
e5cc530b 1569/**
1570 * @uses EWIKI_DB_F_TEXT
1571 * @uses EWIKI_DB_F_BINARY
1572 * @uses EWIKI_DB_F_DISABLED
1573 * @uses EWIKI_DB_F_HTML
1574 * @uses EWIKI_DB_F_READONLY
1575 * @uses EWIKI_DB_F_WRITEABLE
1576 * @return array
1577 */
39fcb981 1578function wiki_admin_get_flagarray() {
1579 $ret = array(
1580 EWIKI_DB_F_TEXT => get_string("flagtxt","wiki"),
1581 EWIKI_DB_F_BINARY => get_string("flagbin","wiki"),
1582 EWIKI_DB_F_DISABLED => get_string("flagoff","wiki"),
1583 EWIKI_DB_F_HTML => get_string("flaghtm","wiki"),
1584 EWIKI_DB_F_READONLY => get_string("flagro","wiki"),
1585 EWIKI_DB_F_WRITEABLE => get_string("flagwr","wiki"),
1586 );
8f0cd6ef 1587
39fcb981 1588 return $ret;
1589}
1590
1591///////// Ewiki Administration. Mostly taken from the ewiki/tools folder and changed
e5cc530b 1592
1593/**
1594 * @param bool $pageflagstatus
1595 * @return object
1596 */
39fcb981 1597function wiki_admin_setpageflags_list($pageflagstatus) {
8f0cd6ef 1598 $FD = wiki_admin_get_flagarray();
7ce73e92 1599 $table = new html_table();
39fcb981 1600 $table->head = array(get_string("pagename","wiki"), get_string("flags","wiki"));
1601 if($pageflagstatus) {
1602 $table->head[]=get_string("status","wiki");
1603 }
8f0cd6ef 1604
39fcb981 1605 $result = ewiki_database("GETALL", array("version", "flags"));
1606 while ($row = $result->get()) {
1607 $id = $row["id"];
1608 $data = ewiki_database("GET", $row);
1609
1610 $cell_pagename="";
1611 $cell_flags="";
1612 if ($data["flags"] & EWIKI_DB_F_TEXT) {
b1503075 1613 $cell_pagename .= '<a href="' . EWIKI_SCRIPT . $id . '">';
39fcb981 1614 } else {
b1503075 1615 $cell_pagename .= '<a href="' . EWIKI_SCRIPT_BINARY . $id . '">';
39fcb981 1616 }
b1503075 1617 $cell_pagename .= s($id) . '</a> / '.get_string("version","wiki").": ".$row["version"];
8f0cd6ef 1618
39fcb981 1619 foreach ($FD as $n=>$str) {
b1503075 1620 $cell_flags .='<input type="checkbox" name="flags['. rawurlencode($id)
1621 . '][' . $n . ']" value="1" '
82056f67 1622 . (($data["flags"] & $n) ? "checked=\"checked\"" : "")
a9ef4a63 1623 . ' />'.$str. ' ';
39fcb981 1624 }
1625 if($pageflagstatus) {
1626 $table->data[]=array($cell_pagename, $cell_flags, $pageflagstatus[$id]);
1627 } else {
1628 $table->data[]=array($cell_pagename, $cell_flags);
1629 }
1630 }
1631 return $table;
1632}
1633
e5cc530b 1634/**
1635 * @param array $pageflags
1636 * @return array Status array
1637 */
39fcb981 1638function wiki_admin_setpageflags($pageflags) {
1639 $FD = wiki_admin_get_flagarray();
8f0cd6ef 1640
39fcb981 1641 $status=array();
8f0cd6ef 1642 if($pageflags) {
39fcb981 1643 foreach($pageflags as $page=>$fa) {
1644
1645 $page = rawurldecode($page);
1646
1647 $flags = 0;
1648 $fstr = "";
1649 foreach($fa as $num=>$isset) {
1650 if ($isset) {
1651 $flags += $num;
1652 $fstr .= ($fstr?",":""). $FD[$num];
1653 }
1654 }
1655
1656 #$status[$page] .= "{$flags}=[{$fstr}]";
1657
1658 $data = ewiki_database("GET", array("id" => $page));
1659
1660 if ($data["flags"] != $flags) {
1661 $data["flags"] = $flags;
1662 $data["author"] = "ewiki-tools, " . ewiki_author();
1663 $data["version"]++;
1664 ewiki_database("WRITE", $data);
1665 $status[$page] = "<b>".get_string("flagsset","wiki")."</b> ".$status[$page];
1666 }
1667 }
1668 }
8f0cd6ef 1669 return $status;
39fcb981 1670}
1671
e5cc530b 1672/**
1673 * @param bool $listall
1674 * @return object
1675 */
39fcb981 1676function wiki_admin_remove_list($listall="") {
1677 /// Table header
7ce73e92 1678 $table = new html_table();
39fcb981 1679 $table->head = array("&nbsp;", get_string("pagename","wiki"), get_string("errororreason","wiki"));
8f0cd6ef 1680
39fcb981 1681 /// Get all pages
1682 $result = ewiki_database("GETALL", array("version"));
1683 $selected = array();
1684
1685 /// User wants to see all pages
1686 if ($listall) {
1687 while ($row = $result->get()) {
a9ef4a63 1688 $selected[$row["id"]] = get_string("listall","wiki")."<br />";
39fcb981 1689 }
1690 }
8f0cd6ef 1691 while ($page = $result->get()) {
39fcb981 1692 $id = $page["id"];
1693 $page = ewiki_database("GET", array("id"=>$id));
1694 $flags = $page["flags"];
8f0cd6ef 1695 #print "$id ".strlen(trim(($page["content"])))."<br />";
39fcb981 1696
1697 if (!strlen(trim(($page["content"]))) && !($flags & EWIKI_DB_F_BINARY)) {
a9ef4a63 1698 @$selected[$id] .= get_string("emptypage","wiki")."<br />";
39fcb981 1699 }
8f0cd6ef 1700
39fcb981 1701 // Check for orphaned pages
1702 $result2 = ewiki_database("SEARCH", array("content" => $id));
1703 $orphanedpage=true;
1704 if ($result2 && $result2->count()) {
1705 while ($row = $result2->get()) {
1706 $checkcontent = ewiki_database("GET", array("id"=>$row["id"]));
1707 $checkcontent = strtolower($checkcontent["content"]);
8f0cd6ef 1708
39fcb981 1709 if(strpos($checkcontent, strtolower($id)) !== false) {
1710 $orphanedpage=false;
1711 }
1712
a9ef4a63 1713 #echo "rc({$row['id']})==>($id): $check2 <br />";
39fcb981 1714 }
1715 }
1716
8f0cd6ef 1717 /// Some more reasons for Deletion...
39fcb981 1718 if ($orphanedpage && $id!=EWIKI_PAGE_INDEX &&!($flags & EWIKI_DB_F_BINARY)) {
a9ef4a63 1719 @$selected[$id] .= get_string("orphanedpage","wiki")."<br />";
39fcb981 1720 }
1721
1722 if ($flags & EWIKI_DB_F_DISABLED) {
a9ef4a63 1723 @$selected[$id] .= get_string("disabledpage","wiki")."<br />";
39fcb981 1724 }
1725
1726 if (($flags & 3) == 3) {
a9ef4a63 1727 @$selected[$id] .= get_string("errorbinandtxt","wiki")."<br />";
39fcb981 1728 }
1729
1730 if (!($flags & 3)) {
a9ef4a63 1731 @$selected[$id] .= get_string("errornotype","wiki")."<br />";
39fcb981 1732 }
1733
1734 if ($flags & EWIKI_DB_F_HTML) {
a9ef4a63 1735 @$selected[$id] .= get_string("errorhtml","wiki")."<br />";
39fcb981 1736 }
1737
1738 if (($flags & EWIKI_DB_F_READONLY) && !($flags & EWIKI_DB_F_BINARY)) {
a9ef4a63 1739 @$selected[$id] .= get_string("readonly","wiki")."<br />";
39fcb981 1740 }
1741
1742 if (($flags & EWIKI_DB_F_READONLY) && ($flags & EWIKI_DB_F_WRITEABLE)) {
a9ef4a63 1743 @$selected[$id] .= get_string("errorroandwr","wiki")."<br />";
39fcb981 1744 }
1745
1746 if (strlen($page["content"]) >= 65536) {
a9ef4a63 1747 @$selected[$id] .= get_string("errorsize","wiki")."<br />";
39fcb981 1748 }
1749
1750 if (strpos($page["refs"], "\n".get_string("deletemewikiword","wiki")."\n")!==false) {
a9ef4a63 1751 @$selected[$id] .= get_string("deletemewikiwordfound","wiki",get_string("deletemewikiword","wiki"))."<br />";
39fcb981 1752 }
1753 }
8f0cd6ef 1754
1755 foreach ($selected as $id => $reason) {
b1503075 1756 $table_checkbox='<input type="checkbox" value="'.rawurlencode($id).'" name="pagestodelete[]" />';
39fcb981 1757
1758 #-- link & id
1759 if (strpos($id, EWIKI_IDF_INTERNAL) === false) {
b1503075 1760 $table_page='<a href="' . ewiki_script("", $id) . '">';
39fcb981 1761 } else {
b1503075 1762 $table_page='<a href="' . ewiki_script_binary("", $id) . '">';
39fcb981 1763 }
b1503075 1764 $table_page .= s($id) . '</a>';
39fcb981 1765
1766 #-- print reason
1767 $table_reason=$reason;
8f0cd6ef 1768
39fcb981 1769 $table->data[]=array($table_checkbox, $table_page, $table_reason);
8f0cd6ef 1770 }
1771
1772 return $table;
39fcb981 1773}
1774
e5cc530b 1775/**
1776 * This function actually removes the pages
1777 * @param array $pagestodelete
1778 * @param object $course
1779 * @param object $wiki
1780 * @param int $userid
1781 * @param int $groupid
1782 * @return string
1783 */
39fcb981 1784function wiki_admin_remove($pagestodelete, $course, $wiki, $userid, $groupid) {
8f0cd6ef 1785 $ret="";
39fcb981 1786 foreach ($pagestodelete as $id) {
1787
1788 $id = rawurldecode($id);
1789
1790 $data = ewiki_database("GET", array("id"=>$id));
1791 for ($version=1; $version<=$data["version"]; $version++) {
1792 ewiki_database("DELETE", array("id"=>$id, "version"=>$version));
1793 if($data["flags"] & EWIKI_DB_F_BINARY) {
1794 $filepath=moodle_binary_get_path($id, $data["meta"], $course, $wiki, $userid, $groupid);
1795 @unlink("$filepath");
1796 }
1797 }
8f0cd6ef 1798
39fcb981 1799 }
1800 return $ret;
1801}
1802
e5cc530b 1803/**
1804 * @param array $pagestostrip
1805 * @param string $version
1806 * @param string $err
1807 * @return object
1808 */
39fcb981 1809function wiki_admin_strip_list($pagestostrip="",$version="",$err="") {
1810 /// Table header
7ce73e92 1811 $table = new html_table();
39fcb981 1812 $table->head = array("&nbsp;", get_string("pagename","wiki"), get_string("deleteversions","wiki"));
8f0cd6ef 1813
39fcb981 1814 $vc=ewiki_database("COUNTVERSIONS", array());
1815 $result = ewiki_database("GETALL",array());
1816 $i=0;
1817 while ($row = $result->get()) {
1818 $id = $row["id"];
1819 if($vc[$id]>1) {
1820 $error="";
1821 if($err[$id]) {
1822 $error=" ".join(", ",$err[$id]);
8f0cd6ef 1823 }
39fcb981 1824 $checked="";
1825 if($pagestostrip=="" || $pagestostrip[$i]) {
82056f67 1826 $checked=" checked=\"checked\"";
39fcb981 1827 }
1828 if($version=="") {
1829 $versiondefault="1-".($row["version"]-1);
1830 } else {
1831 $versiondefault=$version[$i];
1832 }
8f0cd6ef 1833 $table->data[]=array('<input type="checkbox" value="'.rawurlencode($id).'" name="pagestostrip['.$i.']" '.$checked.' />',
2bc0b7a0 1834 '<A HREF="'.EWIKI_SCRIPT.$id.'">'.s($id).'</A> / '.get_string("version","wiki").": ".$row["version"],
a9ef4a63 1835 '<input name="version['.$i.']" value="'.$versiondefault.'" size="7" />'.$error);
8f0cd6ef 1836
39fcb981 1837 }
1838 $i++;
1839 }
1840 return $table;
1841}
1842
e5cc530b 1843/**
1844 * @param array $pagestostrip
1845 * @param string $version
1846 * @param string $err
1847 * @return array
1848 */
39fcb981 1849function wiki_admin_strip_versions($pagestostrip, $version, &$err) {
1850 $ret=array();
1851 foreach ($pagestostrip as $key => $id_ue) {
8f0cd6ef 1852
39fcb981 1853 $id = rawurldecode($id_ue);
1854 if (preg_match('/^(\d+)[-\s._:]+(\d+)$/', trim($version[$key]), $uu)) {
1855 $versA = $uu[1];
1856 $versZ = $uu[2];
8f0cd6ef 1857
39fcb981 1858 // Let the last Version in the database
d2481a47 1859 $checkdata = ewiki_database("GET", array("id" => $id));
39fcb981 1860 if($versZ>=$checkdata["version"]) {
8f0cd6ef 1861 $err[$id][] = get_string("versionrangetoobig","wiki");
39fcb981 1862 } else {
1863 if($versA<=$versZ) {
1864 for ($v=$versA; $v<=$versZ; $v++) {
1865 $ret[$id][]=$v;
1866 }
1867 } else {
1868 $err[$id][]=get_string("wrongversionrange","wiki",$version[$key]);
1869 }
1870 }
1871 }
1872 else {
1873 $err[$id][]=get_string("wrongversionrange","wiki",$version[$key]);
1874 }
1875 }
1876 return $ret;
1877}
8f0cd6ef 1878
e5cc530b 1879/**
1880 * @param array $pagestostrip
1881 */
39fcb981 1882function wiki_admin_strip($pagestostrip) {
1883 /// Purges old page-versions
1884 foreach($pagestostrip as $id => $versions) {
1885 foreach($versions as $version) {
1886 ewiki_database("DELETE", array("id"=>$id, "version"=>$version));
1887 }
1888 }
8f0cd6ef 1889}
39fcb981 1890
e5cc530b 1891/**
1892 * @return array
1893 */
39fcb981 1894function wiki_admin_checklinks_list() {
1895 $ret=array();
1896 $result = ewiki_database("GETALL",array());
1897 while ($row = $result->get()) {
1898 if(!($row["flags"] & EWIKI_DB_F_BINARY)) {
2bc0b7a0 1899 $index=s($row["id"]);
39fcb981 1900 $ret[$index] = $row["id"];
1901 }
1902 }
1903 return $ret;
1904}
1905
e5cc530b 1906/**
1907 * Checks http:// Links
1908 * @return string
1909 */
39fcb981 1910function wiki_admin_checklinks($pagetocheck) {
39fcb981 1911 $ret="";
1912 if($pagetocheck) {
1913 $get = ewiki_database("GET", array("id" => $pagetocheck));
1914 $content = $get["content"];
8f0cd6ef 1915
a9de0242 1916 preg_match_all('_(http.?://[^\s"\'<>#,;]+[^\s"\'<>#,;.])_', $content, $links);
39fcb981 1917 $badlinks = array();
1918 if(!$links[1]) {
a9ef4a63 1919 $ret = get_string("nolinksfound","wiki")."<br /><br />";
39fcb981 1920 } else {
1921 foreach ($links[1] as $href) {
1922 #print "[ $href ]";
8f0cd6ef 1923 #$d = @implode("", @file($href));
39fcb981 1924 $d="";
1925 if($checkfd = @fopen($href, 'r')) {
1926 fclose($checkfd);
1927 $d="OK";
1928 }
1929 if (empty($d) || !strlen(trim($d)) || stristr("not found", $d) || stristr("error 404", $d)) {
a9ef4a63 1930 $ret.="[".get_string("linkdead","wiki")."] $href <br />\n";
39fcb981 1931 $badlinks[] = $href;
1932 } else {
a9ef4a63 1933 $ret.="[".get_string("linkok","wiki")."] $href <br />\n";
39fcb981 1934 }
8f0cd6ef 1935 }
39fcb981 1936 }
8f0cd6ef 1937
39fcb981 1938 /// Remove old Notices
6dbcacee 1939 $content = preg_replace('/ µµ__~\['.get_string("offline","wiki").'\]__µµ /i','', $content);
39fcb981 1940
1941 #-- replace dead links
1942 foreach ($badlinks as $href) {
ee3cc995 1943 $content = preg_replace("\377^(.*)($href)\377m", '$1 µµ__~['.get_string("offline","wiki").']__µµ $2', $content);
39fcb981 1944 }
1945
1946 #-- compare against db content
1947 if ($content != $get["content"]) {
1948 $get["content"] = $content;
1949 $get["version"]++;
1950 $get["author"] = ewiki_author("ewiki_checklinks");
1951 $get["lastmodified"] = time();
1952
1953 ewiki_database("WRITE", $get);
1954 }
1955 }
1956 return $ret;
1957}
1958
e5cc530b 1959/**
1960 * @param bool $proceed
1961 * @param string $authorfieldpattern
1962 * @param int $changesfield
1963 * @param string $howtooperate
1964 * @param int $deleteversions
1965 * @return string
1966 */
39fcb981 1967function wiki_admin_revert($proceed, $authorfieldpattern, $changesfield, $howtooperate, $deleteversions) {
1968 $ret="";
1969 #-- params
1970 $m_time = $changesfield * 3600;
1971 $depth = $deleteversions - 1;
1972 $depth = ($depth>0?$depth:0);
8f0cd6ef 1973
39fcb981 1974 #-- walk through
1975 $result = ewiki_database("GETALL", array("id", "author", "lastmodified"));
1976 while ($row = $result->get()) {
1977 $id = $row["id"];
1978 #-- which versions to check
1979 $verZ = $row["version"];
1980 if ($howtooperate=="lastonly") {
1981 $verA = $verZ;
1982 }
1983 else {
1984 $verA = $verZ-$depth;
8f0cd6ef 1985 if ($verA <= 0) {
39fcb981 1986 $verA = 1;
1987 }
1988 }
1989
1990 for ($ver=$verA; $ver<=$verZ; $ver++) {
1991 #-- load current $ver database entry
1992 if ($verA != $verZ) {
1993 $row = ewiki_database("GET", array("id"=>$id, "version"=>$ver));
1994 }
1995
1996 #-- match
1997 if (stristr($row["author"], $authorfieldpattern) && ($row["lastmodified"] + $m_time > time())) {
1998 $ret .= "$id (".get_string("versionstodelete","wiki").": ";
1999 #-- delete multiple versions
2000 if ($howtooperate=="allsince") {
2001 while ($ver<=$verZ) {
2002 $ret .= " $ver";
2003 if ($proceed) {
2004 ewiki_database("DELETE", array("id"=>$id, "version"=>$ver));
2005 }
2006 $ver++;
2007 }
2008 }
2009 #-- or just the affected one
2010 else {
2011 $ret .= " $ver";
2012 if ($proceed) {
2013 ewiki_database("DELETE", $row);
2014 }
2015 }
a9ef4a63 2016 $ret .= ")<br />";
39fcb981 2017 break;
2018 }
2019 } #-- for($ver)
2020 } #-- while($row)
2021 return $ret;
2022}
f3221af9 2023
2024
e5cc530b 2025/**
2026 * @return array
2027 */
f3221af9 2028function wiki_get_view_actions() {
2029 return array('view','view all');
2030}
2031
e5cc530b 2032/**
2033 * @return array
2034 */
f3221af9 2035function wiki_get_post_actions() {
2036 return array('hack');
2037}
2038
2039
4db1861a 2040/**
2041 * Obtains an editing lock on a wiki page.
e5cc530b 2042 *
2043 * @global object
2044 * @global object
4db1861a 2045 * @param int $wikiid ID of wiki object.
2046 * @param string $pagename Name of page.
2047 * @return array Two-element array with a boolean true (if lock has been obtained)
2048 * or false (if lock was held by somebody else). If lock was held by someone else,
6022c4f5 2049 * the values of the wiki_locks entry are held in the second element; if lock was
2050 * held by current user then the the second element has a member ->id only.
4db1861a 2051 */
2052function wiki_obtain_lock($wikiid,$pagename) {
655b09ca 2053 global $USER, $DB;
f84d6a8d 2054
2ee60b49 2055 // Check for lock
4db1861a 2056 $alreadyownlock=false;
655b09ca 2057 if($lock=$DB->get_record('wiki_locks', array('pagename'=>$pagename,'wikiid'=>$wikiid))) {
4db1861a 2058 // Consider the page locked if the lock has been confirmed within WIKI_LOCK_PERSISTENCE seconds
2059 if($lock->lockedby==$USER->id) {
2060 // Cool, it's our lock, do nothing except remember it in session
2061 $lockid=$lock->id;
2062 $alreadyownlock=true;
2063 } else if(time()-$lock->lockedseen < WIKI_LOCK_PERSISTENCE) {
2ee60b49 2064 return array(false,$lock);
4db1861a 2065 } else {
2066 // Not locked any more. Get rid of the old lock record.
bb4b6010 2067 $DB->delete_records('wiki_locks', array('pagename'=>$pagename,'wikiid'=>$wikiid));
f84d6a8d 2068 }
4db1861a 2069 }
f84d6a8d 2070
4db1861a 2071 // Add lock
f84d6a8d 2072 if(!$alreadyownlock) {
2ee60b49 2073 // Lock page
2074 $newlock=new stdClass;
2075 $newlock->lockedby=$USER->id;
2076 $newlock->lockedsince=time();
2077 $newlock->lockedseen=$newlock->lockedsince;
2078 $newlock->wikiid=$wikiid;
2079 $newlock->pagename=$pagename;
bb4b6010 2080 $lockid = $DB->insert_record('wiki_locks',$newlock);
4db1861a 2081 }
f84d6a8d 2082
4db1861a 2083 // Store lock information in session so we can clear it later
2084 if(!array_key_exists(SESSION_WIKI_LOCKS,$_SESSION)) {
2ee60b49 2085 $_SESSION[SESSION_WIKI_LOCKS]=array();
4db1861a 2086 }
2ee60b49 2087 $_SESSION[SESSION_WIKI_LOCKS][$wikiid.'_'.$pagename]=$lockid;
6022c4f5 2088 $lockdata=new StdClass;
2089 $lockdata->id=$lockid;
2090 return array(true,$lockdata);
4db1861a 2091}
2092
2093/**
2094 * If the user has an editing lock, releases it. Has no effect otherwise.
2095 * Note that it doesn't matter if this isn't called (as happens if their
2096 * browser crashes or something) since locks time out anyway. This is just
2097 * to avoid confusion of the 'what? it says I'm editing that page but I'm
2098 * not, I just saved it!' variety.
e5cc530b 2099 *
2100 * @global object
4db1861a 2101 * @param int $wikiid ID of wiki object.
2102 * @param string $pagename Name of page.
2103 */
f84d6a8d 2104function wiki_release_lock($wikiid,$pagename) {
655b09ca 2105 global $DB;
2106
4db1861a 2107 if(!array_key_exists(SESSION_WIKI_LOCKS,$_SESSION)) {
2ee60b49 2108 // No locks at all in session
2109 return;
4db1861a 2110 }
f84d6a8d 2111
4db1861a 2112 $key=$wikiid.'_'.$pagename;
f84d6a8d 2113
4db1861a 2114 if(array_key_exists($key,$_SESSION[SESSION_WIKI_LOCKS])) {
2ee60b49 2115 $lockid=$_SESSION[SESSION_WIKI_LOCKS][$key];
2116 unset($_SESSION[SESSION_WIKI_LOCKS][$key]);
bb4b6010 2117 $DB->delete_records('wiki_locks', array('id'=>$lockid));
f84d6a8d 2118 }
4db1861a 2119}
2120
f432bebf 2121/**
2122 * Returns all other caps used in module
e5cc530b 2123 *
2124 * @return array
f432bebf 2125 */
2126function wiki_get_extra_capabilities() {
2127 return array('moodle/site:accessallgroups', 'moodle/site:viewfullnames');
2128}
4db1861a 2129
42f103be 2130/**
e5cc530b 2131 * @uses FEATURE_GROUPS
2132 * @uses FEATURE_GROUPINGS
2133 * @uses FEATURE_GROUPMEMBERSONLY
2134 * @uses FEATURE_MOD_INTRO
2135 * @uses FEATURE_COMPLETION_TRACKS_VIEWS
2136 * @uses FEATURE_GRADE_HAS_GRADE
2137 * @uses FEATURE_GRADE_OUTCOMES
42f103be 2138 * @param string $feature FEATURE_xx constant for requested feature
2139 * @return mixed True if module supports feature, null if doesn't know
2140 */
2141function wiki_supports($feature) {
2142 switch($feature) {
2143 case FEATURE_GROUPS: return true;
2144 case FEATURE_GROUPINGS: return true;
2145 case FEATURE_GROUPMEMBERSONLY: return true;
dc5c2bd9 2146 case FEATURE_MOD_INTRO: return true;
42f103be 2147 case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
2148 case FEATURE_GRADE_HAS_GRADE: return false;
2149 case FEATURE_GRADE_OUTCOMES: return true;
2150
2151 default: return null;
2152 }
17da2e6f 2153}