PageRenderTime 30ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/mod/wiki/lib.php

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