Commit | Line | Data |
---|---|---|
00710f4c DC |
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/>. | |
17 | ||
18 | /** | |
19 | * This contains functions and classes that will be used by scripts in wiki module | |
20 | * | |
593b8385 | 21 | * @package mod_wiki |
7db38cd5 SH |
22 | * @copyright 2009 Marc Alier, Jordi Piguillem marc.alier@upc.edu |
23 | * @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu | |
00710f4c DC |
24 | * |
25 | * @author Jordi Piguillem | |
26 | * @author Marc Alier | |
27 | * @author David Jimenez | |
28 | * @author Josep Arus | |
29 | * @author Daniel Serrano | |
30 | * @author Kenneth Riba | |
31 | * | |
32 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
33 | */ | |
34 | ||
35 | require_once($CFG->dirroot . '/mod/wiki/lib.php'); | |
36 | require_once($CFG->dirroot . '/mod/wiki/parser/parser.php'); | |
99d19c13 | 37 | require_once($CFG->libdir . '/filelib.php'); |
00710f4c DC |
38 | |
39 | define('WIKI_REFRESH_CACHE_TIME', 30); // @TODO: To be deleted. | |
40 | define('FORMAT_CREOLE', '37'); | |
41 | define('FORMAT_NWIKI', '38'); | |
42 | define('NO_VALID_RATE', '-999'); | |
43 | define('IMPROVEMENT', '+'); | |
44 | define('EQUAL', '='); | |
45 | define('WORST', '-'); | |
46 | ||
47 | define('LOCK_TIMEOUT', 30); | |
48 | ||
49 | /** | |
50 | * Get a wiki instance | |
51 | * @param int $wikiid the instance id of wiki | |
52 | */ | |
53 | function wiki_get_wiki($wikiid) { | |
54 | global $DB; | |
55 | ||
56 | return $DB->get_record('wiki', array('id' => $wikiid)); | |
57 | } | |
58 | ||
59 | /** | |
60 | * Get sub wiki instances with same wiki id | |
61 | * @param int $wikiid | |
62 | */ | |
63 | function wiki_get_subwikis($wikiid) { | |
64 | global $DB; | |
65 | return $DB->get_records('wiki_subwikis', array('wikiid' => $wikiid)); | |
66 | } | |
67 | ||
68 | /** | |
69 | * Get a sub wiki instance by wiki id and group id | |
70 | * @param int $wikiid | |
71 | * @param int $groupid | |
72 | * @return object | |
73 | */ | |
74 | function wiki_get_subwiki_by_group($wikiid, $groupid, $userid = 0) { | |
75 | global $DB; | |
76 | return $DB->get_record('wiki_subwikis', array('wikiid' => $wikiid, 'groupid' => $groupid, 'userid' => $userid)); | |
77 | } | |
78 | ||
79 | /** | |
80 | * Get a sub wiki instace by instance id | |
81 | * @param int $subwikiid | |
82 | * @return object | |
83 | */ | |
84 | function wiki_get_subwiki($subwikiid) { | |
85 | global $DB; | |
86 | return $DB->get_record('wiki_subwikis', array('id' => $subwikiid)); | |
87 | ||
88 | } | |
89 | ||
90 | /** | |
91 | * Add a new sub wiki instance | |
92 | * @param int $wikiid | |
93 | * @param int $groupid | |
94 | * @return int $insertid | |
95 | */ | |
96 | function wiki_add_subwiki($wikiid, $groupid, $userid = 0) { | |
97 | global $DB; | |
98 | ||
99 | $record = new StdClass(); | |
100 | $record->wikiid = $wikiid; | |
101 | $record->groupid = $groupid; | |
102 | $record->userid = $userid; | |
103 | ||
104 | $insertid = $DB->insert_record('wiki_subwikis', $record); | |
105 | return $insertid; | |
106 | } | |
107 | ||
108 | /** | |
109 | * Get a wiki instance by pageid | |
110 | * @param int $pageid | |
111 | * @return object | |
112 | */ | |
113 | function wiki_get_wiki_from_pageid($pageid) { | |
114 | global $DB; | |
115 | ||
9730c555 JP |
116 | $sql = "SELECT w.* |
117 | FROM {wiki} w, {wiki_subwikis} s, {wiki_pages} p | |
118 | WHERE p.id = ? AND | |
119 | p.subwikiid = s.id AND | |
120 | s.wikiid = w.id"; | |
00710f4c DC |
121 | |
122 | return $DB->get_record_sql($sql, array($pageid)); | |
123 | } | |
124 | ||
125 | /** | |
126 | * Get a wiki page by pageid | |
127 | * @param int $pageid | |
128 | * @return object | |
129 | */ | |
130 | function wiki_get_page($pageid) { | |
131 | global $DB; | |
132 | return $DB->get_record('wiki_pages', array('id' => $pageid)); | |
133 | } | |
134 | ||
135 | /** | |
136 | * Get latest version of wiki page | |
137 | * @param int $pageid | |
138 | * @return object | |
139 | */ | |
140 | function wiki_get_current_version($pageid) { | |
141 | global $DB; | |
142 | ||
9730c555 JP |
143 | // @TODO: Fix this query |
144 | $sql = "SELECT * | |
145 | FROM {wiki_versions} | |
146 | WHERE pageid = ? | |
70b082fa | 147 | ORDER BY version DESC"; |
54352ac9 PS |
148 | $records = $DB->get_records_sql($sql, array($pageid), 0, 1); |
149 | return array_pop($records); | |
00710f4c DC |
150 | |
151 | } | |
152 | ||
153 | /** | |
154 | * Alias of wiki_get_current_version | |
155 | * @TODO, does the exactly same thing as wiki_get_current_version, should be removed | |
156 | * @param int $pageid | |
157 | * @return object | |
158 | */ | |
159 | function wiki_get_last_version($pageid) { | |
160 | return wiki_get_current_version($pageid); | |
161 | } | |
162 | ||
163 | /** | |
164 | * Get page section | |
165 | * @param int $pageid | |
166 | * @param string $section | |
167 | */ | |
168 | function wiki_get_section_page($page, $section) { | |
169 | ||
170 | $version = wiki_get_current_version($page->id); | |
171 | return wiki_parser_proxy::get_section($version->content, $version->contentformat, $section); | |
172 | } | |
173 | ||
174 | /** | |
175 | * Get a wiki page by page title | |
176 | * @param int $swid, sub wiki id | |
177 | * @param string $title | |
178 | * @return object | |
179 | */ | |
180 | function wiki_get_page_by_title($swid, $title) { | |
181 | global $DB; | |
182 | return $DB->get_record('wiki_pages', array('subwikiid' => $swid, 'title' => $title)); | |
183 | } | |
184 | ||
185 | /** | |
186 | * Get a version record by record id | |
187 | * @param int $versionid, the version id | |
188 | * @return object | |
189 | */ | |
190 | function wiki_get_version($versionid) { | |
191 | global $DB; | |
192 | return $DB->get_record('wiki_versions', array('id' => $versionid)); | |
193 | } | |
194 | ||
195 | /** | |
196 | * Get first page of wiki instace | |
197 | * @param int $subwikiid | |
198 | * @param int $module, wiki instance object | |
199 | */ | |
37dcd4b6 | 200 | function wiki_get_first_page($subwikid, $module = null) { |
00710f4c | 201 | global $DB, $USER; |
00710f4c | 202 | |
9730c555 JP |
203 | $sql = "SELECT p.* |
204 | FROM {wiki} w, {wiki_subwikis} s, {wiki_pages} p | |
205 | WHERE s.id = ? AND | |
206 | s.wikiid = w.id AND | |
207 | w.firstpagetitle = p.title AND | |
208 | p.subwikiid = s.id"; | |
00710f4c DC |
209 | return $DB->get_record_sql($sql, array($subwikid)); |
210 | } | |
211 | ||
212 | function wiki_save_section($wikipage, $sectiontitle, $sectioncontent, $userid) { | |
213 | ||
214 | $wiki = wiki_get_wiki_from_pageid($wikipage->id); | |
215 | $cm = get_coursemodule_from_instance('wiki', $wiki->id); | |
1df23626 | 216 | $context = context_module::instance($cm->id); |
00710f4c DC |
217 | |
218 | if (has_capability('mod/wiki:editpage', $context)) { | |
219 | $version = wiki_get_current_version($wikipage->id); | |
220 | $content = wiki_parser_proxy::get_section($version->content, $version->contentformat, $sectiontitle, true); | |
221 | ||
222 | $newcontent = $content[0] . $sectioncontent . $content[2]; | |
223 | ||
224 | return wiki_save_page($wikipage, $newcontent, $userid); | |
225 | } else { | |
226 | return false; | |
227 | } | |
228 | } | |
229 | ||
230 | /** | |
231 | * Save page content | |
232 | * @param object $wikipage | |
233 | * @param string $newcontent | |
234 | * @param int $userid | |
235 | */ | |
236 | function wiki_save_page($wikipage, $newcontent, $userid) { | |
237 | global $DB; | |
238 | ||
239 | $wiki = wiki_get_wiki_from_pageid($wikipage->id); | |
240 | $cm = get_coursemodule_from_instance('wiki', $wiki->id); | |
1df23626 | 241 | $context = context_module::instance($cm->id); |
00710f4c DC |
242 | |
243 | if (has_capability('mod/wiki:editpage', $context)) { | |
244 | $version = wiki_get_current_version($wikipage->id); | |
245 | ||
246 | $version->content = $newcontent; | |
247 | $version->userid = $userid; | |
248 | $version->version++; | |
249 | $version->timecreated = time(); | |
fb92417b | 250 | $version->id = $DB->insert_record('wiki_versions', $version); |
00710f4c DC |
251 | |
252 | $wikipage->timemodified = $version->timecreated; | |
253 | $wikipage->userid = $userid; | |
254 | $return = wiki_refresh_cachedcontent($wikipage, $newcontent); | |
fb92417b RT |
255 | $event = \mod_wiki\event\page_updated::create( |
256 | array( | |
257 | 'context' => $context, | |
258 | 'objectid' => $wikipage->id, | |
259 | 'relateduserid' => $userid, | |
260 | 'other' => array( | |
261 | 'newcontent' => $newcontent | |
262 | ) | |
263 | )); | |
264 | $event->add_record_snapshot('wiki', $wiki); | |
265 | $event->add_record_snapshot('wiki_pages', $wikipage); | |
266 | $event->add_record_snapshot('wiki_versions', $version); | |
267 | $event->trigger(); | |
00710f4c DC |
268 | return $return; |
269 | } else { | |
270 | return false; | |
271 | } | |
272 | } | |
273 | ||
274 | function wiki_refresh_cachedcontent($page, $newcontent = null) { | |
275 | global $DB; | |
276 | ||
277 | $version = wiki_get_current_version($page->id); | |
79f0bac6 DC |
278 | if (empty($version)) { |
279 | return null; | |
280 | } | |
00710f4c DC |
281 | if (!isset($newcontent)) { |
282 | $newcontent = $version->content; | |
283 | } | |
284 | ||
285 | $options = array('swid' => $page->subwikiid, 'pageid' => $page->id); | |
286 | $parseroutput = wiki_parse_content($version->contentformat, $newcontent, $options); | |
287 | $page->cachedcontent = $parseroutput['toc'] . $parseroutput['parsed_text']; | |
288 | $page->timerendered = time(); | |
289 | $DB->update_record('wiki_pages', $page); | |
290 | ||
291 | wiki_refresh_page_links($page, $parseroutput['link_count']); | |
292 | ||
293 | return array('page' => $page, 'sections' => $parseroutput['repeated_sections'], 'version' => $version->version); | |
294 | } | |
0e729875 | 295 | |
00710f4c | 296 | /** |
0e729875 RT |
297 | * Restore a page with specified version. |
298 | * | |
299 | * @param stdClass $wikipage wiki page record | |
300 | * @param stdClass $version wiki page version to restore | |
301 | * @param context_module $context context of wiki module | |
302 | * @return stdClass restored page | |
00710f4c | 303 | */ |
0e729875 RT |
304 | function wiki_restore_page($wikipage, $version, $context) { |
305 | $return = wiki_save_page($wikipage, $version->content, $version->userid); | |
306 | $event = \mod_wiki\event\page_version_restored::create( | |
307 | array( | |
308 | 'context' => $context, | |
309 | 'objectid' => $version->id, | |
310 | 'other' => array( | |
311 | 'pageid' => $wikipage->id | |
312 | ) | |
313 | )); | |
314 | $event->add_record_snapshot('wiki_versions', $version); | |
315 | $event->trigger(); | |
00710f4c DC |
316 | return $return['page']; |
317 | } | |
318 | ||
319 | function wiki_refresh_page_links($page, $links) { | |
320 | global $DB; | |
321 | ||
322 | $DB->delete_records('wiki_links', array('frompageid' => $page->id)); | |
323 | foreach ($links as $linkname => $linkinfo) { | |
324 | ||
325 | $newlink = new stdClass(); | |
326 | $newlink->subwikiid = $page->subwikiid; | |
327 | $newlink->frompageid = $page->id; | |
328 | ||
329 | if ($linkinfo['new']) { | |
330 | $newlink->tomissingpage = $linkname; | |
331 | } else { | |
332 | $newlink->topageid = $linkinfo['pageid']; | |
333 | } | |
334 | ||
79f0bac6 DC |
335 | try { |
336 | $DB->insert_record('wiki_links', $newlink); | |
337 | } catch (dml_exception $e) { | |
338 | debugging($e->getMessage()); | |
339 | } | |
00710f4c DC |
340 | |
341 | } | |
342 | } | |
343 | ||
344 | /** | |
345 | * Create a new wiki page, if the page exists, return existing pageid | |
346 | * @param int $swid | |
347 | * @param string $title | |
348 | * @param string $format | |
349 | * @param int $userid | |
350 | */ | |
351 | function wiki_create_page($swid, $title, $format, $userid) { | |
4c4e6591 | 352 | global $DB; |
7bc03dd5 JP |
353 | $subwiki = wiki_get_subwiki($swid); |
354 | $cm = get_coursemodule_from_instance('wiki', $subwiki->wikiid); | |
1df23626 | 355 | $context = context_module::instance($cm->id); |
7bc03dd5 | 356 | require_capability('mod/wiki:editpage', $context); |
00710f4c DC |
357 | // if page exists |
358 | if ($page = wiki_get_page_by_title($swid, $title)) { | |
359 | return $page->id; | |
360 | } | |
361 | ||
362 | // Creating a new empty version | |
363 | $version = new stdClass(); | |
364 | $version->content = ''; | |
365 | $version->contentformat = $format; | |
366 | $version->version = 0; | |
367 | $version->timecreated = time(); | |
368 | $version->userid = $userid; | |
369 | ||
370 | $versionid = null; | |
a9637e7d | 371 | $versionid = $DB->insert_record('wiki_versions', $version); |
00710f4c DC |
372 | |
373 | // Createing a new empty page | |
374 | $page = new stdClass(); | |
375 | $page->subwikiid = $swid; | |
376 | $page->title = $title; | |
377 | $page->cachedcontent = ''; | |
378 | $page->timecreated = $version->timecreated; | |
379 | $page->timemodified = $version->timecreated; | |
380 | $page->timerendered = $version->timecreated; | |
381 | $page->userid = $userid; | |
382 | $page->pageviews = 0; | |
383 | $page->readonly = 0; | |
384 | ||
385 | $pageid = $DB->insert_record('wiki_pages', $page); | |
386 | ||
387 | // Setting the pageid | |
388 | $version->id = $versionid; | |
389 | $version->pageid = $pageid; | |
390 | $DB->update_record('wiki_versions', $version); | |
391 | ||
a8481a66 RT |
392 | $event = \mod_wiki\event\page_created::create( |
393 | array( | |
394 | 'context' => $context, | |
395 | 'objectid' => $pageid | |
396 | ) | |
397 | ); | |
398 | $event->trigger(); | |
399 | ||
00710f4c DC |
400 | wiki_make_cache_expire($page->title); |
401 | return $pageid; | |
402 | } | |
403 | ||
404 | function wiki_make_cache_expire($pagename) { | |
405 | global $DB; | |
406 | ||
9730c555 JP |
407 | $sql = "UPDATE {wiki_pages} |
408 | SET timerendered = 0 | |
409 | WHERE id IN ( SELECT l.frompageid | |
410 | FROM {wiki_links} l | |
411 | WHERE l.tomissingpage = ? | |
412 | )"; | |
00710f4c DC |
413 | $DB->execute ($sql, array($pagename)); |
414 | } | |
415 | ||
416 | /** | |
417 | * Get a specific version of page | |
418 | * @param int $pageid | |
419 | * @param int $version | |
420 | */ | |
421 | function wiki_get_wiki_page_version($pageid, $version) { | |
422 | global $DB; | |
423 | return $DB->get_record('wiki_versions', array('pageid' => $pageid, 'version' => $version)); | |
424 | } | |
425 | ||
426 | /** | |
427 | * Get version list | |
428 | * @param int $pageid | |
429 | * @param int $limitfrom | |
430 | * @param int $limitnum | |
431 | */ | |
432 | function wiki_get_wiki_page_versions($pageid, $limitfrom, $limitnum) { | |
433 | global $DB; | |
434 | return $DB->get_records('wiki_versions', array('pageid' => $pageid), 'version DESC', '*', $limitfrom, $limitnum); | |
435 | } | |
436 | ||
437 | /** | |
438 | * Count the number of page version | |
439 | * @param int $pageid | |
440 | */ | |
441 | function wiki_count_wiki_page_versions($pageid) { | |
442 | global $DB; | |
443 | return $DB->count_records('wiki_versions', array('pageid' => $pageid)); | |
444 | } | |
445 | ||
446 | /** | |
447 | * Get linked from page | |
448 | * @param int $pageid | |
449 | */ | |
450 | function wiki_get_linked_to_pages($pageid) { | |
451 | global $DB; | |
452 | return $DB->get_records('wiki_links', array('frompageid' => $pageid)); | |
453 | } | |
454 | ||
455 | /** | |
456 | * Get linked from page | |
457 | * @param int $pageid | |
458 | */ | |
459 | function wiki_get_linked_from_pages($pageid) { | |
460 | global $DB; | |
461 | return $DB->get_records('wiki_links', array('topageid' => $pageid)); | |
462 | } | |
463 | ||
464 | /** | |
465 | * Get pages which user have been edited | |
466 | * @param int $swid | |
467 | * @param int $userid | |
468 | */ | |
469 | function wiki_get_contributions($swid, $userid) { | |
470 | global $DB; | |
471 | ||
9730c555 JP |
472 | $sql = "SELECT v.* |
473 | FROM {wiki_versions} v, {wiki_pages} p | |
474 | WHERE p.subwikiid = ? AND | |
475 | v.pageid = p.id AND | |
476 | v.userid = ?"; | |
00710f4c DC |
477 | |
478 | return $DB->get_records_sql($sql, array($swid, $userid)); | |
479 | } | |
480 | ||
481 | /** | |
482 | * Get missing or empty pages in wiki | |
483 | * @param int $swid sub wiki id | |
484 | */ | |
485 | function wiki_get_missing_or_empty_pages($swid) { | |
486 | global $DB; | |
487 | ||
9730c555 JP |
488 | $sql = "SELECT DISTINCT p.title, p.id, p.subwikiid |
489 | FROM {wiki} w, {wiki_subwikis} s, {wiki_pages} p | |
490 | WHERE s.wikiid = w.id and | |
491 | s.id = ? and | |
492 | w.firstpagetitle != p.title and | |
493 | p.subwikiid = ? and | |
494 | 1 = (SELECT count(*) | |
495 | FROM {wiki_versions} v | |
496 | WHERE v.pageid = p.id) | |
497 | UNION | |
498 | SELECT DISTINCT l.tomissingpage as title, 0 as id, l.subwikiid | |
499 | FROM {wiki_links} l | |
500 | WHERE l.subwikiid = ? and | |
501 | l.topageid = 0"; | |
00710f4c DC |
502 | |
503 | return $DB->get_records_sql($sql, array($swid, $swid, $swid)); | |
504 | } | |
505 | ||
506 | /** | |
507 | * Get pages list in wiki | |
508 | * @param int $swid sub wiki id | |
96abf9af | 509 | * @param string $sort How to sort the pages. By default, title ASC. |
00710f4c | 510 | */ |
96abf9af | 511 | function wiki_get_page_list($swid, $sort = 'title ASC') { |
00710f4c | 512 | global $DB; |
96abf9af | 513 | $records = $DB->get_records('wiki_pages', array('subwikiid' => $swid), $sort); |
00710f4c DC |
514 | return $records; |
515 | } | |
516 | ||
517 | /** | |
518 | * Return a list of orphaned wikis for one specific subwiki | |
519 | * @global object | |
520 | * @param int $swid sub wiki id | |
521 | */ | |
522 | function wiki_get_orphaned_pages($swid) { | |
523 | global $DB; | |
524 | ||
9730c555 JP |
525 | $sql = "SELECT p.id, p.title |
526 | FROM {wiki_pages} p, {wiki} w , {wiki_subwikis} s | |
527 | WHERE p.subwikiid = ? | |
528 | AND s.id = ? | |
529 | AND w.id = s.wikiid | |
530 | AND p.title != w.firstpagetitle | |
92b145dc | 531 | AND p.id NOT IN (SELECT topageid FROM {wiki_links} WHERE subwikiid = ?)"; |
00710f4c | 532 | |
9730c555 | 533 | return $DB->get_records_sql($sql, array($swid, $swid, $swid)); |
00710f4c DC |
534 | } |
535 | ||
536 | /** | |
537 | * Search wiki title | |
538 | * @param int $swid sub wiki id | |
539 | * @param string $search | |
540 | */ | |
541 | function wiki_search_title($swid, $search) { | |
542 | global $DB; | |
75b986e7 JP |
543 | |
544 | return $DB->get_records_select('wiki_pages', "subwikiid = ? AND title LIKE ?", array($swid, '%'.$search.'%')); | |
00710f4c DC |
545 | } |
546 | ||
547 | /** | |
548 | * Search wiki content | |
549 | * @param int $swid sub wiki id | |
550 | * @param string $search | |
551 | */ | |
552 | function wiki_search_content($swid, $search) { | |
553 | global $DB; | |
75b986e7 JP |
554 | |
555 | return $DB->get_records_select('wiki_pages', "subwikiid = ? AND cachedcontent LIKE ?", array($swid, '%'.$search.'%')); | |
00710f4c DC |
556 | } |
557 | ||
558 | /** | |
559 | * Search wiki title and content | |
560 | * @param int $swid sub wiki id | |
561 | * @param string $search | |
562 | */ | |
563 | function wiki_search_all($swid, $search) { | |
564 | global $DB; | |
75b986e7 JP |
565 | |
566 | return $DB->get_records_select('wiki_pages', "subwikiid = ? AND (cachedcontent LIKE ? OR title LIKE ?)", array($swid, '%'.$search.'%', '%'.$search.'%')); | |
00710f4c DC |
567 | } |
568 | ||
569 | /** | |
9ffd2726 | 570 | * Get user data |
00710f4c DC |
571 | */ |
572 | function wiki_get_user_info($userid) { | |
9ffd2726 JP |
573 | global $DB; |
574 | return $DB->get_record('user', array('id' => $userid)); | |
00710f4c DC |
575 | } |
576 | ||
577 | /** | |
578 | * Increase page view nubmer | |
579 | * @param int $page, database record | |
580 | */ | |
581 | function wiki_increment_pageviews($page) { | |
582 | global $DB; | |
583 | ||
584 | $page->pageviews++; | |
585 | $DB->update_record('wiki_pages', $page); | |
586 | } | |
587 | ||
588 | //---------------------------------------------------------- | |
589 | //---------------------------------------------------------- | |
590 | ||
591 | /** | |
592 | * Text format supported by wiki module | |
593 | */ | |
594 | function wiki_get_formats() { | |
44c0751b | 595 | return array('html', 'creole', 'nwiki'); |
00710f4c DC |
596 | } |
597 | ||
598 | /** | |
599 | * Parses a string with the wiki markup language in $markup. | |
600 | * | |
601 | * @return Array or false when something wrong has happened. | |
602 | * | |
603 | * Returned array contains the following fields: | |
604 | * 'parsed_text' => String. Contains the parsed wiki content. | |
605 | * 'unparsed_text' => String. Constains the original wiki content. | |
606 | * 'link_count' => Array of array('destination' => ..., 'new' => "is new?"). Contains the internal wiki links found in the wiki content. | |
607 | * 'deleted_sections' => the list of deleted sections. | |
608 | * '' => | |
609 | * | |
610 | * @author Josep Arús Pous | |
611 | **/ | |
612 | function wiki_parse_content($markup, $pagecontent, $options = array()) { | |
613 | global $PAGE; | |
614 | ||
615 | $subwiki = wiki_get_subwiki($options['swid']); | |
616 | $cm = get_coursemodule_from_instance("wiki", $subwiki->wikiid); | |
1df23626 | 617 | $context = context_module::instance($cm->id); |
00710f4c | 618 | |
c464a238 SH |
619 | $parser_options = array( |
620 | 'link_callback' => '/mod/wiki/locallib.php:wiki_parser_link', | |
12c9bbbd DC |
621 | 'link_callback_args' => array('swid' => $options['swid']), |
622 | 'table_callback' => '/mod/wiki/locallib.php:wiki_parser_table', | |
623 | 'real_path_callback' => '/mod/wiki/locallib.php:wiki_parser_real_path', | |
624 | 'real_path_callback_args' => array( | |
625 | 'context' => $context, | |
626 | 'component' => 'mod_wiki', | |
627 | 'filearea' => 'attachments', | |
628 | 'subwikiid'=> $subwiki->id, | |
629 | 'pageid' => $options['pageid'] | |
630 | ), | |
631 | 'pageid' => $options['pageid'], | |
632 | 'pretty_print' => (isset($options['pretty_print']) && $options['pretty_print']), | |
633 | 'printable' => (isset($options['printable']) && $options['printable']) | |
634 | ); | |
00710f4c DC |
635 | |
636 | return wiki_parser_proxy::parse($pagecontent, $markup, $parser_options); | |
637 | } | |
638 | ||
639 | /** | |
640 | * This function is the parser callback to parse wiki links. | |
641 | * | |
642 | * It returns the necesary information to print a link. | |
643 | * | |
644 | * NOTE: Empty pages and non-existent pages must be print in red color. | |
645 | * | |
4c4e6591 SH |
646 | * !!!!!! IMPORTANT !!!!!! |
647 | * It is critical that you call format_string on the content before it is used. | |
00710f4c | 648 | * |
4c4e6591 SH |
649 | * @param string|page_wiki $link name of a page |
650 | * @param array $options | |
651 | * @return array Array('content' => string, 'url' => string, 'new' => bool, 'link_info' => array) | |
00710f4c DC |
652 | * |
653 | * @TODO Doc return and options | |
654 | */ | |
655 | function wiki_parser_link($link, $options = null) { | |
656 | global $CFG; | |
657 | ||
658 | if (is_object($link)) { | |
659 | $parsedlink = array('content' => $link->title, 'url' => $CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $link->id, 'new' => false, 'link_info' => array('link' => $link->title, 'pageid' => $link->id, 'new' => false)); | |
660 | ||
661 | $version = wiki_get_current_version($link->id); | |
662 | if ($version->version == 0) { | |
663 | $parsedlink['new'] = true; | |
664 | } | |
665 | return $parsedlink; | |
666 | } else { | |
667 | $swid = $options['swid']; | |
668 | ||
669 | if ($page = wiki_get_page_by_title($swid, $link)) { | |
670 | $parsedlink = array('content' => $link, 'url' => $CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $page->id, 'new' => false, 'link_info' => array('link' => $link, 'pageid' => $page->id, 'new' => false)); | |
671 | ||
672 | $version = wiki_get_current_version($page->id); | |
673 | if ($version->version == 0) { | |
674 | $parsedlink['new'] = true; | |
675 | } | |
676 | ||
677 | return $parsedlink; | |
678 | ||
679 | } else { | |
680 | return array('content' => $link, 'url' => $CFG->wwwroot . '/mod/wiki/create.php?swid=' . $swid . '&title=' . urlencode($link) . '&action=new', 'new' => true, 'link_info' => array('link' => $link, 'new' => true, 'pageid' => 0)); | |
681 | } | |
682 | } | |
683 | } | |
684 | ||
685 | /** | |
686 | * Returns the table fully parsed (HTML) | |
687 | * | |
688 | * @return HTML for the table $table | |
689 | * @author Josep Arús Pous | |
690 | * | |
691 | **/ | |
692 | function wiki_parser_table($table) { | |
693 | global $OUTPUT; | |
694 | ||
695 | $htmltable = new html_table(); | |
696 | ||
697 | $headers = $table[0]; | |
698 | $htmltable->head = array(); | |
699 | foreach ($headers as $h) { | |
700 | $htmltable->head[] = $h[1]; | |
701 | } | |
702 | ||
703 | array_shift($table); | |
704 | $htmltable->data = array(); | |
705 | foreach ($table as $row) { | |
706 | $row_data = array(); | |
707 | foreach ($row as $r) { | |
708 | $row_data[] = $r[1]; | |
709 | } | |
710 | $htmltable->data[] = $row_data; | |
711 | } | |
712 | ||
713 | return html_writer::table($htmltable); | |
714 | } | |
715 | ||
716 | /** | |
717 | * Returns an absolute path link, unless there is no such link. | |
718 | * | |
c464a238 SH |
719 | * @param string $url Link's URL or filename |
720 | * @param stdClass $context filearea params | |
721 | * @param string $component The component the file is associated with | |
722 | * @param string $filearea The filearea the file is stored in | |
723 | * @param int $swid Sub wiki id | |
00710f4c | 724 | * |
c464a238 | 725 | * @return string URL for files full path |
00710f4c DC |
726 | */ |
727 | ||
12c9bbbd | 728 | function wiki_parser_real_path($url, $context, $component, $filearea, $swid) { |
00710f4c DC |
729 | global $CFG; |
730 | ||
731 | if (preg_match("/^(?:http|ftp)s?\:\/\//", $url)) { | |
732 | return $url; | |
733 | } else { | |
12c9bbbd DC |
734 | |
735 | $file = 'pluginfile.php'; | |
736 | if (!$CFG->slasharguments) { | |
737 | $file = $file . '?file='; | |
738 | } | |
739 | $baseurl = "$CFG->wwwroot/$file/{$context->id}/$component/$filearea/$swid/"; | |
740 | // it is a file in current file area | |
741 | return $baseurl . $url; | |
00710f4c DC |
742 | } |
743 | } | |
744 | ||
745 | /** | |
746 | * Returns the token used by a wiki language to represent a given tag or "object" (bold -> **) | |
747 | * | |
748 | * @return A string when it has only one token at the beginning (f. ex. lists). An array composed by 2 strings when it has 2 tokens, one at the beginning and one at the end (f. ex. italics). Returns false otherwise. | |
749 | * @author Josep Arús Pous | |
750 | **/ | |
751 | function wiki_parser_get_token($markup, $name) { | |
752 | ||
753 | return wiki_parser_proxy::get_token($name, $markup); | |
754 | } | |
755 | ||
756 | /** | |
757 | * Checks if current user can view a subwiki | |
758 | * | |
3a7b9b76 MG |
759 | * @param stdClass $subwiki usually record from {wiki_subwikis}. Must contain fields 'wikiid', 'groupid', 'userid'. |
760 | * If it also contains fields 'course' and 'groupmode' from table {wiki} it will save extra DB query. | |
761 | * @param stdClass $wiki optional wiki object if known | |
762 | * @return bool | |
00710f4c | 763 | */ |
3a7b9b76 | 764 | function wiki_user_can_view($subwiki, $wiki = null) { |
00710f4c DC |
765 | global $USER; |
766 | ||
3a7b9b76 MG |
767 | if (empty($wiki) || $wiki->id != $subwiki->wikiid) { |
768 | $wiki = wiki_get_wiki($subwiki->wikiid); | |
769 | } | |
770 | $modinfo = get_fast_modinfo($wiki->course); | |
771 | if (!isset($modinfo->instances['wiki'][$subwiki->wikiid])) { | |
772 | // Module does not exist. | |
773 | return false; | |
774 | } | |
775 | $cm = $modinfo->instances['wiki'][$subwiki->wikiid]; | |
776 | if (!$cm->uservisible) { | |
777 | // The whole module is not visible to the current user. | |
778 | return false; | |
779 | } | |
1df23626 | 780 | $context = context_module::instance($cm->id); |
00710f4c DC |
781 | |
782 | // Working depending on activity groupmode | |
783 | switch (groups_get_activity_groupmode($cm)) { | |
784 | case NOGROUPS: | |
785 | ||
786 | if ($wiki->wikimode == 'collaborative') { | |
787 | // Collaborative Mode: | |
788 | // There is one wiki for all the class. | |
789 | // | |
790 | // Only view capbility needed | |
cece1791 | 791 | return has_capability('mod/wiki:viewpage', $context); |
00710f4c DC |
792 | } else if ($wiki->wikimode == 'individual') { |
793 | // Individual Mode: | |
794 | // Each person owns a wiki. | |
795 | if ($subwiki->userid == $USER->id) { | |
796 | // Only the owner of the wiki can view it | |
cece1791 | 797 | return has_capability('mod/wiki:viewpage', $context); |
00710f4c DC |
798 | } else { // User has special capabilities |
799 | // User must have: | |
800 | // mod/wiki:viewpage capability | |
801 | // and | |
802 | // mod/wiki:managewiki capability | |
cece1791 DC |
803 | $view = has_capability('mod/wiki:viewpage', $context); |
804 | $manage = has_capability('mod/wiki:managewiki', $context); | |
00710f4c DC |
805 | |
806 | return $view && $manage; | |
807 | } | |
808 | } else { | |
809 | //Error | |
810 | return false; | |
811 | } | |
812 | case SEPARATEGROUPS: | |
813 | // Collaborative and Individual Mode | |
814 | // | |
815 | // Collaborative Mode: | |
816 | // There is one wiki per group. | |
817 | // Individual Mode: | |
818 | // Each person owns a wiki. | |
819 | if ($wiki->wikimode == 'collaborative' || $wiki->wikimode == 'individual') { | |
820 | // Only members of subwiki group could view that wiki | |
3a7b9b76 | 821 | if (in_array($subwiki->groupid, $modinfo->get_groups($cm->groupingid))) { |
00710f4c | 822 | // Only view capability needed |
cece1791 | 823 | return has_capability('mod/wiki:viewpage', $context); |
00710f4c DC |
824 | |
825 | } else { // User is not part of that group | |
826 | // User must have: | |
827 | // mod/wiki:managewiki capability | |
828 | // or | |
829 | // moodle/site:accessallgroups capability | |
830 | // and | |
831 | // mod/wiki:viewpage capability | |
cece1791 DC |
832 | $view = has_capability('mod/wiki:viewpage', $context); |
833 | $manage = has_capability('mod/wiki:managewiki', $context); | |
834 | $access = has_capability('moodle/site:accessallgroups', $context); | |
00710f4c | 835 | return ($manage || $access) && $view; |
37dcd4b6 | 836 | } |
00710f4c DC |
837 | } else { |
838 | //Error | |
839 | return false; | |
840 | } | |
841 | case VISIBLEGROUPS: | |
842 | // Collaborative and Individual Mode | |
843 | // | |
844 | // Collaborative Mode: | |
845 | // There is one wiki per group. | |
846 | // Individual Mode: | |
847 | // Each person owns a wiki. | |
848 | if ($wiki->wikimode == 'collaborative' || $wiki->wikimode == 'individual') { | |
849 | // Everybody can read all wikis | |
850 | // | |
851 | // Only view capability needed | |
cece1791 | 852 | return has_capability('mod/wiki:viewpage', $context); |
00710f4c DC |
853 | } else { |
854 | //Error | |
855 | return false; | |
856 | } | |
857 | default: // Error | |
858 | return false; | |
859 | } | |
860 | } | |
861 | ||
862 | /** | |
863 | * Checks if current user can edit a subwiki | |
864 | * | |
865 | * @param $subwiki | |
866 | */ | |
867 | function wiki_user_can_edit($subwiki) { | |
868 | global $USER; | |
869 | ||
870 | $wiki = wiki_get_wiki($subwiki->wikiid); | |
871 | $cm = get_coursemodule_from_instance('wiki', $wiki->id); | |
1df23626 | 872 | $context = context_module::instance($cm->id); |
00710f4c DC |
873 | |
874 | // Working depending on activity groupmode | |
875 | switch (groups_get_activity_groupmode($cm)) { | |
876 | case NOGROUPS: | |
877 | ||
878 | if ($wiki->wikimode == 'collaborative') { | |
879 | // Collaborative Mode: | |
880 | // There is a wiki for all the class. | |
881 | // | |
882 | // Only edit capbility needed | |
cece1791 | 883 | return has_capability('mod/wiki:editpage', $context); |
00710f4c DC |
884 | } else if ($wiki->wikimode == 'individual') { |
885 | // Individual Mode | |
886 | // There is a wiki per user | |
887 | ||
888 | // Only the owner of that wiki can edit it | |
889 | if ($subwiki->userid == $USER->id) { | |
cece1791 | 890 | return has_capability('mod/wiki:editpage', $context); |
00710f4c DC |
891 | } else { // Current user is not the owner of that wiki. |
892 | ||
893 | // User must have: | |
894 | // mod/wiki:editpage capability | |
895 | // and | |
896 | // mod/wiki:managewiki capability | |
cece1791 DC |
897 | $edit = has_capability('mod/wiki:editpage', $context); |
898 | $manage = has_capability('mod/wiki:managewiki', $context); | |
00710f4c DC |
899 | |
900 | return $edit && $manage; | |
901 | } | |
902 | } else { | |
903 | //Error | |
904 | return false; | |
905 | } | |
906 | case SEPARATEGROUPS: | |
907 | if ($wiki->wikimode == 'collaborative') { | |
908 | // Collaborative Mode: | |
909 | // There is one wiki per group. | |
910 | // | |
911 | // Only members of subwiki group could edit that wiki | |
bb05505e | 912 | if (groups_is_member($subwiki->groupid)) { |
00710f4c | 913 | // Only edit capability needed |
cece1791 | 914 | return has_capability('mod/wiki:editpage', $context); |
00710f4c DC |
915 | } else { // User is not part of that group |
916 | // User must have: | |
917 | // mod/wiki:managewiki capability | |
918 | // and | |
919 | // moodle/site:accessallgroups capability | |
920 | // and | |
921 | // mod/wiki:editpage capability | |
cece1791 DC |
922 | $manage = has_capability('mod/wiki:managewiki', $context); |
923 | $access = has_capability('moodle/site:accessallgroups', $context); | |
924 | $edit = has_capability('mod/wiki:editpage', $context); | |
00710f4c DC |
925 | return $manage && $access && $edit; |
926 | } | |
927 | } else if ($wiki->wikimode == 'individual') { | |
928 | // Individual Mode: | |
929 | // Each person owns a wiki. | |
930 | // | |
931 | // Only the owner of that wiki can edit it | |
932 | if ($subwiki->userid == $USER->id) { | |
cece1791 | 933 | return has_capability('mod/wiki:editpage', $context); |
00710f4c DC |
934 | } else { // Current user is not the owner of that wiki. |
935 | // User must have: | |
936 | // mod/wiki:managewiki capability | |
937 | // and | |
938 | // moodle/site:accessallgroups capability | |
939 | // and | |
940 | // mod/wiki:editpage capability | |
cece1791 DC |
941 | $manage = has_capability('mod/wiki:managewiki', $context); |
942 | $access = has_capability('moodle/site:accessallgroups', $context); | |
943 | $edit = has_capability('mod/wiki:editpage', $context); | |
00710f4c DC |
944 | return $manage && $access && $edit; |
945 | } | |
946 | } else { | |
947 | //Error | |
948 | return false; | |
949 | } | |
950 | case VISIBLEGROUPS: | |
951 | if ($wiki->wikimode == 'collaborative') { | |
952 | // Collaborative Mode: | |
953 | // There is one wiki per group. | |
954 | // | |
955 | // Only members of subwiki group could edit that wiki | |
dc0cabb4 | 956 | if (groups_is_member($subwiki->groupid)) { |
00710f4c | 957 | // Only edit capability needed |
cece1791 | 958 | return has_capability('mod/wiki:editpage', $context); |
00710f4c DC |
959 | } else { // User is not part of that group |
960 | // User must have: | |
961 | // mod/wiki:managewiki capability | |
962 | // and | |
963 | // mod/wiki:editpage capability | |
cece1791 DC |
964 | $manage = has_capability('mod/wiki:managewiki', $context); |
965 | $edit = has_capability('mod/wiki:editpage', $context); | |
00710f4c DC |
966 | return $manage && $edit; |
967 | } | |
968 | } else if ($wiki->wikimode == 'individual') { | |
969 | // Individual Mode: | |
970 | // Each person owns a wiki. | |
971 | // | |
972 | // Only the owner of that wiki can edit it | |
973 | if ($subwiki->userid == $USER->id) { | |
cece1791 | 974 | return has_capability('mod/wiki:editpage', $context); |
00710f4c DC |
975 | } else { // Current user is not the owner of that wiki. |
976 | // User must have: | |
977 | // mod/wiki:managewiki capability | |
978 | // and | |
979 | // mod/wiki:editpage capability | |
cece1791 DC |
980 | $manage = has_capability('mod/wiki:managewiki', $context); |
981 | $edit = has_capability('mod/wiki:editpage', $context); | |
00710f4c DC |
982 | return $manage && $edit; |
983 | } | |
984 | } else { | |
985 | //Error | |
986 | return false; | |
987 | } | |
988 | default: // Error | |
989 | return false; | |
990 | } | |
991 | } | |
992 | ||
993 | //---------------- | |
994 | // Locks | |
995 | //---------------- | |
996 | ||
997 | /** | |
998 | * Checks if a page-section is locked. | |
999 | * | |
1000 | * @return true if the combination of section and page is locked, FALSE otherwise. | |
1001 | */ | |
1002 | function wiki_is_page_section_locked($pageid, $userid, $section = null) { | |
1003 | global $DB; | |
1004 | ||
1005 | $sql = "pageid = ? AND lockedat > ? AND userid != ?"; | |
1006 | $params = array($pageid, time(), $userid); | |
1007 | ||
1008 | if (!empty($section)) { | |
1009 | $sql .= " AND (sectionname = ? OR sectionname IS null)"; | |
1010 | $params[] = $section; | |
1011 | } | |
1012 | ||
1013 | return $DB->record_exists_select('wiki_locks', $sql, $params); | |
1014 | } | |
1015 | ||
1016 | /** | |
1017 | * Inserts or updates a wiki_locks record. | |
1018 | */ | |
1019 | function wiki_set_lock($pageid, $userid, $section = null, $insert = false) { | |
1020 | global $DB; | |
1021 | ||
1022 | if (wiki_is_page_section_locked($pageid, $userid, $section)) { | |
1023 | return false; | |
1024 | } | |
1025 | ||
1026 | $params = array('pageid' => $pageid, 'userid' => $userid, 'sectionname' => $section); | |
1027 | ||
1028 | $lock = $DB->get_record('wiki_locks', $params); | |
1029 | ||
1030 | if (!empty($lock)) { | |
1031 | $DB->update_record('wiki_locks', array('id' => $lock->id, 'lockedat' => time() + LOCK_TIMEOUT)); | |
1032 | } else if ($insert) { | |
1033 | $DB->insert_record('wiki_locks', array('pageid' => $pageid, 'sectionname' => $section, 'userid' => $userid, 'lockedat' => time() + 30)); | |
1034 | } | |
1035 | ||
1036 | return true; | |
1037 | } | |
1038 | ||
1039 | /** | |
1040 | * Deletes wiki_locks that are not in use. (F.Ex. after submitting the changes). If no userid is present, it deletes ALL the wiki_locks of a specific page. | |
b3dd79d1 RT |
1041 | * |
1042 | * @param int $pageid page id. | |
1043 | * @param int $userid id of user for which lock is deleted. | |
1044 | * @param string $section section to be deleted. | |
1045 | * @param bool $delete_from_db deleted from db. | |
1046 | * @param bool $delete_section_and_page delete section and page version. | |
00710f4c DC |
1047 | */ |
1048 | function wiki_delete_locks($pageid, $userid = null, $section = null, $delete_from_db = true, $delete_section_and_page = false) { | |
1049 | global $DB; | |
1050 | ||
b3dd79d1 RT |
1051 | $wiki = wiki_get_wiki_from_pageid($pageid); |
1052 | $cm = get_coursemodule_from_instance('wiki', $wiki->id); | |
1053 | $context = context_module::instance($cm->id); | |
1054 | ||
00710f4c DC |
1055 | $params = array('pageid' => $pageid); |
1056 | ||
1057 | if (!empty($userid)) { | |
1058 | $params['userid'] = $userid; | |
1059 | } | |
1060 | ||
1061 | if (!empty($section)) { | |
1062 | $params['sectionname'] = $section; | |
1063 | } | |
1064 | ||
1065 | if ($delete_from_db) { | |
1066 | $DB->delete_records('wiki_locks', $params); | |
1067 | if ($delete_section_and_page && !empty($section)) { | |
1068 | $params['sectionname'] = null; | |
1069 | $DB->delete_records('wiki_locks', $params); | |
1070 | } | |
b3dd79d1 RT |
1071 | $event = \mod_wiki\event\page_locks_deleted::create( |
1072 | array( | |
1073 | 'context' => $context, | |
1074 | 'objectid' => $pageid, | |
1075 | 'relateduserid' => $userid, | |
1076 | 'other' => array( | |
1077 | 'section' => $section | |
1078 | ) | |
1079 | )); | |
1080 | // No need to add snapshot, as important data is section, userid and pageid, which is part of event. | |
1081 | $event->trigger(); | |
00710f4c DC |
1082 | } else { |
1083 | $DB->set_field('wiki_locks', 'lockedat', time(), $params); | |
1084 | } | |
1085 | } | |
1086 | ||
1087 | /** | |
1088 | * Deletes wiki_locks that expired 1 hour ago. | |
1089 | */ | |
1090 | function wiki_delete_old_locks() { | |
1091 | global $DB; | |
1092 | ||
1093 | $DB->delete_records_select('wiki_locks', "lockedat < ?", array(time() - 3600)); | |
1094 | } | |
1095 | ||
ac0a82cf RT |
1096 | /** |
1097 | * Deletes wiki_links. It can be sepecific link or links attached in subwiki | |
1098 | * | |
1099 | * @global mixed $DB database object | |
1100 | * @param int $linkid id of the link to be deleted | |
1101 | * @param int $topageid links to the specific page | |
1102 | * @param int $frompageid links from specific page | |
1103 | * @param int $subwikiid links to subwiki | |
1104 | */ | |
1105 | function wiki_delete_links($linkid = null, $topageid = null, $frompageid = null, $subwikiid = null) { | |
1106 | global $DB; | |
1107 | $params = array(); | |
1108 | ||
1109 | // if link id is givien then don't check for anything else | |
1110 | if (!empty($linkid)) { | |
1111 | $params['id'] = $linkid; | |
1112 | } else { | |
1113 | if (!empty($topageid)) { | |
1114 | $params['topageid'] = $topageid; | |
1115 | } | |
1116 | if (!empty($frompageid)) { | |
1117 | $params['frompageid'] = $frompageid; | |
1118 | } | |
1119 | if (!empty($subwikiid)) { | |
1120 | $params['subwikiid'] = $subwikiid; | |
1121 | } | |
1122 | } | |
1123 | ||
1124 | //Delete links if any params are passed, else nothing to delete. | |
1125 | if (!empty($params)) { | |
1126 | $DB->delete_records('wiki_links', $params); | |
1127 | } | |
1128 | } | |
1129 | ||
1130 | /** | |
1131 | * Delete wiki synonyms related to subwikiid or page | |
1132 | * | |
1133 | * @param int $subwikiid id of sunbwiki | |
1134 | * @param int $pageid id of page | |
1135 | */ | |
1136 | function wiki_delete_synonym($subwikiid, $pageid = null) { | |
1137 | global $DB; | |
1138 | ||
1139 | $params = array('subwikiid' => $subwikiid); | |
1140 | if (!is_null($pageid)) { | |
1141 | $params['pageid'] = $pageid; | |
1142 | } | |
1143 | $DB->delete_records('wiki_synonyms', $params, IGNORE_MISSING); | |
1144 | } | |
1145 | ||
1146 | /** | |
1147 | * Delete pages and all related data | |
1148 | * | |
1149 | * @param mixed $context context in which page needs to be deleted. | |
1150 | * @param mixed $pageids id's of pages to be deleted | |
1151 | * @param int $subwikiid id of the subwiki for which all pages should be deleted | |
1152 | */ | |
1153 | function wiki_delete_pages($context, $pageids = null, $subwikiid = null) { | |
d6a54be3 | 1154 | global $DB, $CFG; |
ac0a82cf RT |
1155 | |
1156 | if (!empty($pageids) && is_int($pageids)) { | |
1157 | $pageids = array($pageids); | |
1158 | } else if (!empty($subwikiid)) { | |
1159 | $pageids = wiki_get_page_list($subwikiid); | |
1160 | } | |
1161 | ||
1162 | //If there is no pageid then return as we can't delete anything. | |
1163 | if (empty($pageids)) { | |
1164 | return; | |
1165 | } | |
1166 | ||
1167 | /// Delete page and all it's relevent data | |
1168 | foreach ($pageids as $pageid) { | |
1169 | if (is_object($pageid)) { | |
1170 | $pageid = $pageid->id; | |
1171 | } | |
1172 | ||
1173 | //Delete page comments | |
1174 | $comments = wiki_get_comments($context->id, $pageid); | |
1175 | foreach ($comments as $commentid => $commentvalue) { | |
1176 | wiki_delete_comment($commentid, $context, $pageid); | |
1177 | } | |
1178 | ||
1179 | //Delete page tags | |
b0b2c93d | 1180 | core_tag_tag::remove_all_item_tags('mod_wiki', 'wiki_pages', $pageid); |
ac0a82cf RT |
1181 | |
1182 | //Delete Synonym | |
1183 | wiki_delete_synonym($subwikiid, $pageid); | |
1184 | ||
1185 | //Delete all page versions | |
d6a54be3 | 1186 | wiki_delete_page_versions(array($pageid=>array(0)), $context); |
ac0a82cf RT |
1187 | |
1188 | //Delete all page locks | |
1189 | wiki_delete_locks($pageid); | |
1190 | ||
1191 | //Delete all page links | |
1192 | wiki_delete_links(null, $pageid); | |
1193 | ||
ac0a82cf | 1194 | $params = array('id' => $pageid); |
d6a54be3 RT |
1195 | |
1196 | // Get page before deleting. | |
1197 | $page = $DB->get_record('wiki_pages', $params); | |
1198 | ||
1199 | //Delete page | |
ac0a82cf | 1200 | $DB->delete_records('wiki_pages', $params); |
d6a54be3 RT |
1201 | |
1202 | // Trigger page_deleted event. | |
1203 | $event = \mod_wiki\event\page_deleted::create( | |
1204 | array( | |
1205 | 'context' => $context, | |
1206 | 'objectid' => $pageid, | |
1207 | 'other' => array('subwikiid' => $subwikiid) | |
1208 | )); | |
1209 | $event->add_record_snapshot('wiki_pages', $page); | |
1210 | $event->trigger(); | |
ac0a82cf RT |
1211 | } |
1212 | } | |
1213 | ||
1214 | /** | |
1215 | * Delete specificed versions of a page or versions created by users | |
1216 | * if version is 0 then it will remove all versions of the page | |
1217 | * | |
1218 | * @param array $deleteversions delete versions for a page | |
d6a54be3 | 1219 | * @param context_module $context module context |
ac0a82cf | 1220 | */ |
d6a54be3 | 1221 | function wiki_delete_page_versions($deleteversions, $context = null) { |
ac0a82cf RT |
1222 | global $DB; |
1223 | ||
1224 | /// delete page-versions | |
1225 | foreach ($deleteversions as $id => $versions) { | |
d6a54be3 RT |
1226 | $params = array('pageid' => $id); |
1227 | if (is_null($context)) { | |
1228 | $wiki = wiki_get_wiki_from_pageid($id); | |
1229 | $cm = get_coursemodule_from_instance('wiki', $wiki->id); | |
1230 | $context = context_module::instance($cm->id); | |
1231 | } | |
1232 | // Delete all versions, if version specified is 0. | |
1233 | if (in_array(0, $versions)) { | |
1234 | $oldversions = $DB->get_records('wiki_versions', $params); | |
ac0a82cf | 1235 | $DB->delete_records('wiki_versions', $params, IGNORE_MISSING); |
d6a54be3 RT |
1236 | } else { |
1237 | list($insql, $param) = $DB->get_in_or_equal($versions); | |
1238 | $insql .= ' AND pageid = ?'; | |
1239 | array_push($param, $params['pageid']); | |
1240 | $oldversions = $DB->get_recordset_select('wiki_versions', 'version ' . $insql, $param); | |
1241 | $DB->delete_records_select('wiki_versions', 'version ' . $insql, $param); | |
1242 | } | |
1243 | foreach ($oldversions as $version) { | |
1244 | // Trigger page version deleted event. | |
1245 | $event = \mod_wiki\event\page_version_deleted::create( | |
1246 | array( | |
1247 | 'context' => $context, | |
1248 | 'objectid' => $version->id, | |
1249 | 'other' => array( | |
1250 | 'pageid' => $id | |
1251 | ) | |
1252 | )); | |
1253 | $event->add_record_snapshot('wiki_versions', $version); | |
1254 | $event->trigger(); | |
ac0a82cf RT |
1255 | } |
1256 | } | |
1257 | } | |
1258 | ||
9bf1b716 JP |
1259 | function wiki_get_comment($commentid){ |
1260 | global $DB; | |
becf81c7 | 1261 | return $DB->get_record('comments', array('id' => $commentid)); |
9bf1b716 JP |
1262 | } |
1263 | ||
00710f4c DC |
1264 | /** |
1265 | * Returns all comments by context and pageid | |
1266 | * | |
e94f6c65 RT |
1267 | * @param int $contextid Current context id |
1268 | * @param int $pageid Current pageid | |
00710f4c | 1269 | **/ |
9ffd2726 | 1270 | function wiki_get_comments($contextid, $pageid) { |
00710f4c DC |
1271 | global $DB; |
1272 | ||
cde6172d | 1273 | return $DB->get_records('comments', array('contextid' => $contextid, 'itemid' => $pageid, 'commentarea' => 'wiki_page'), 'timecreated ASC'); |
00710f4c DC |
1274 | } |
1275 | ||
1276 | /** | |
1277 | * Add comments ro database | |
1278 | * | |
1279 | * @param object $context. Current context | |
1280 | * @param int $pageid. Current pageid | |
1281 | * @param string $content. Content of the comment | |
1282 | * @param string editor. Version of editor we are using. | |
1283 | **/ | |
1284 | function wiki_add_comment($context, $pageid, $content, $editor) { | |
1285 | global $CFG; | |
1286 | require_once($CFG->dirroot . '/comment/lib.php'); | |
1287 | ||
1288 | list($context, $course, $cm) = get_context_info_array($context->id); | |
1289 | $cmt = new stdclass(); | |
1290 | $cmt->context = $context; | |
1291 | $cmt->itemid = $pageid; | |
ab422920 | 1292 | $cmt->area = 'wiki_page'; |
00710f4c | 1293 | $cmt->course = $course; |
d846488e | 1294 | $cmt->component = 'mod_wiki'; |
00710f4c DC |
1295 | |
1296 | $manager = new comment($cmt); | |
1297 | ||
1298 | if ($editor == 'creole') { | |
1299 | $manager->add($content, FORMAT_CREOLE); | |
1300 | } else if ($editor == 'html') { | |
1301 | $manager->add($content, FORMAT_HTML); | |
1302 | } else if ($editor == 'nwiki') { | |
1303 | $manager->add($content, FORMAT_NWIKI); | |
1304 | } | |
1305 | ||
1306 | } | |
1307 | ||
1308 | /** | |
1309 | * Delete comments from database | |
1310 | * | |
1311 | * @param $idcomment. Id of comment which will be deleted | |
1312 | * @param $context. Current context | |
1313 | * @param $pageid. Current pageid | |
1314 | **/ | |
1315 | function wiki_delete_comment($idcomment, $context, $pageid) { | |
1316 | global $CFG; | |
1317 | require_once($CFG->dirroot . '/comment/lib.php'); | |
1318 | ||
1319 | list($context, $course, $cm) = get_context_info_array($context->id); | |
6bdfef5d | 1320 | $cmt = new stdClass(); |
00710f4c DC |
1321 | $cmt->context = $context; |
1322 | $cmt->itemid = $pageid; | |
ab422920 | 1323 | $cmt->area = 'wiki_page'; |
00710f4c | 1324 | $cmt->course = $course; |
d846488e | 1325 | $cmt->component = 'mod_wiki'; |
00710f4c DC |
1326 | |
1327 | $manager = new comment($cmt); | |
1328 | $manager->delete($idcomment); | |
1329 | ||
1330 | } | |
1331 | ||
1332 | /** | |
1333 | * Delete al comments from wiki | |
1334 | * | |
1335 | **/ | |
1336 | function wiki_delete_comments_wiki() { | |
1337 | global $PAGE, $DB; | |
1338 | ||
1339 | $cm = $PAGE->cm; | |
1df23626 | 1340 | $context = context_module::instance($cm->id); |
00710f4c DC |
1341 | |
1342 | $table = 'comments'; | |
1343 | $select = 'contextid = ?'; | |
1344 | ||
1345 | $DB->delete_records_select($table, $select, array($context->id)); | |
1346 | ||
1347 | } | |
1348 | ||
1349 | function wiki_add_progress($pageid, $oldversionid, $versionid, $progress) { | |
1350 | global $DB; | |
1351 | for ($v = $oldversionid + 1; $v <= $versionid; $v++) { | |
1352 | $user = wiki_get_wiki_page_id($pageid, $v); | |
1353 | ||
1354 | $DB->insert_record('wiki_progress', array('userid' => $user->userid, 'pageid' => $pageid, 'versionid' => $v, 'progress' => $progress)); | |
1355 | } | |
1356 | } | |
1357 | ||
1358 | function wiki_get_wiki_page_id($pageid, $id) { | |
1359 | global $DB; | |
1360 | return $DB->get_record('wiki_versions', array('pageid' => $pageid, 'id' => $id)); | |
1361 | } | |
1362 | ||
1363 | function wiki_print_page_content($page, $context, $subwikiid) { | |
1364 | global $OUTPUT, $CFG; | |
1365 | ||
1366 | if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) { | |
1367 | $content = wiki_refresh_cachedcontent($page); | |
1368 | $page = $content['page']; | |
1369 | } | |
1370 | ||
1371 | if (isset($content)) { | |
1372 | $box = ''; | |
1373 | foreach ($content['sections'] as $s) { | |
1374 | $box .= '<p>' . get_string('repeatedsection', 'wiki', $s) . '</p>'; | |
1375 | } | |
1376 | ||
1377 | if (!empty($box)) { | |
1378 | echo $OUTPUT->box($box); | |
1379 | } | |
1380 | } | |
64f93798 | 1381 | $html = file_rewrite_pluginfile_urls($page->cachedcontent, 'pluginfile.php', $context->id, 'mod_wiki', 'attachments', $subwikiid); |
2f8b49d5 | 1382 | $html = format_text($html, FORMAT_MOODLE, array('overflowdiv'=>true, 'allowid'=>true)); |
00710f4c DC |
1383 | echo $OUTPUT->box($html); |
1384 | ||
b0b2c93d MG |
1385 | echo $OUTPUT->tag_list(core_tag_tag::get_item_tags('mod_wiki', 'wiki_pages', $page->id), |
1386 | null, 'wiki-tags'); | |
00710f4c DC |
1387 | |
1388 | wiki_increment_pageviews($page); | |
1389 | } | |
1390 | ||
1391 | /** | |
1392 | * This function trims any given text and returns it with some dots at the end | |
1393 | * | |
1394 | * @param string $text | |
1395 | * @param string $limit | |
1396 | * | |
1397 | * @return string | |
1398 | */ | |
1399 | function wiki_trim_string($text, $limit = 25) { | |
1400 | ||
2f1e464a PS |
1401 | if (core_text::strlen($text) > $limit) { |
1402 | $text = core_text::substr($text, 0, $limit) . '...'; | |
00710f4c DC |
1403 | } |
1404 | ||
1405 | return $text; | |
1406 | } | |
1407 | ||
1408 | /** | |
1409 | * Prints default edit form fields and buttons | |
1410 | * | |
1411 | * @param string $format Edit form format (html, creole...) | |
1412 | * @param integer $version Version number. A negative number means no versioning. | |
1413 | */ | |
1414 | ||
1415 | function wiki_print_edit_form_default_fields($format, $pageid, $version = -1, $upload = false, $deleteuploads = array()) { | |
1416 | global $CFG, $PAGE, $OUTPUT; | |
1417 | ||
1418 | echo '<input type="hidden" name="sesskey" value="' . sesskey() . '" />'; | |
1419 | ||
1420 | if ($version >= 0) { | |
1421 | echo '<input type="hidden" name="version" value="' . $version . '" />'; | |
1422 | } | |
1423 | ||
1424 | echo '<input type="hidden" name="format" value="' . $format . '"/>'; | |
1425 | ||
1426 | //attachments | |
1427 | require_once($CFG->dirroot . '/lib/form/filemanager.php'); | |
1428 | ||
1429 | $filemanager = new MoodleQuickForm_filemanager('attachments', get_string('wikiattachments', 'wiki'), array('id' => 'attachments'), array('subdirs' => false, 'maxfiles' => 99, 'maxbytes' => $CFG->maxbytes)); | |
1430 | ||
1431 | $value = file_get_submitted_draft_itemid('attachments'); | |
1432 | if (!empty($value) && !$upload) { | |
1433 | $filemanager->setValue($value); | |
1434 | } | |
1435 | ||
1436 | echo "<fieldset class=\"wiki-upload-section clearfix\"><legend class=\"ftoggler\">" . get_string("uploadtitle", 'wiki') . "</legend>"; | |
1437 | ||
1438 | echo $OUTPUT->container_start('mdl-align wiki-form-center aaaaa'); | |
1439 | print $filemanager->toHtml(); | |
1440 | echo $OUTPUT->container_end(); | |
1441 | ||
1442 | $cm = $PAGE->cm; | |
1df23626 | 1443 | $context = context_module::instance($cm->id); |
00710f4c DC |
1444 | |
1445 | echo $OUTPUT->container_start('mdl-align wiki-form-center wiki-upload-table'); | |
1446 | wiki_print_upload_table($context, 'wiki_upload', $pageid, $deleteuploads); | |
1447 | echo $OUTPUT->container_end(); | |
1448 | ||
1449 | echo "</fieldset>"; | |
1450 | ||
1451 | echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('save', 'wiki') . '"/>'; | |
1452 | echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('upload', 'wiki') . '"/>'; | |
1453 | echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('preview') . '"/>'; | |
1454 | echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('cancel') . '" />'; | |
1455 | } | |
1456 | ||
1457 | /** | |
1458 | * Prints a table with the files attached to a wiki page | |
1459 | * @param object $context | |
1460 | * @param string $filearea | |
1461 | * @param int $fileitemid | |
1462 | * @param array deleteuploads | |
1463 | */ | |
1464 | function wiki_print_upload_table($context, $filearea, $fileitemid, $deleteuploads = array()) { | |
1465 | global $CFG, $OUTPUT; | |
1466 | ||
1467 | $htmltable = new html_table(); | |
1468 | ||
1469 | $htmltable->head = array(get_string('deleteupload', 'wiki'), get_string('uploadname', 'wiki'), get_string('uploadactions', 'wiki')); | |
1470 | ||
1471 | $fs = get_file_storage(); | |
64f93798 | 1472 | $files = $fs->get_area_files($context->id, 'mod_wiki', $filearea, $fileitemid); //TODO: this is weird (skodak) |
00710f4c DC |
1473 | |
1474 | foreach ($files as $file) { | |
1475 | if (!$file->is_directory()) { | |
1476 | $checkbox = '<input type="checkbox" name="deleteupload[]", value="' . $file->get_pathnamehash() . '"'; | |
1477 | ||
1478 | if (in_array($file->get_pathnamehash(), $deleteuploads)) { | |
1479 | $checkbox .= ' checked="checked"'; | |
1480 | } | |
1481 | ||
1482 | $checkbox .= " />"; | |
1483 | ||
1484 | $htmltable->data[] = array($checkbox, '<a href="' . file_encode_url($CFG->wwwroot . '/pluginfile.php', '/' . $context->id . '/wiki_upload/' . $fileitemid . '/' . $file->get_filename()) . '">' . $file->get_filename() . '</a>', ""); | |
1485 | } | |
1486 | } | |
1487 | ||
1488 | print '<h3 class="upload-table-title">' . get_string('uploadfiletitle', 'wiki') . "</h3>"; | |
1489 | print html_writer::table($htmltable); | |
1490 | } | |
1491 | ||
1492 | /** | |
1493 | * Generate wiki's page tree | |
1494 | * | |
4c4e6591 SH |
1495 | * @param page_wiki $page. A wiki page object |
1496 | * @param navigation_node $node. Starting navigation_node | |
1497 | * @param array $keys. An array to store keys | |
00710f4c DC |
1498 | * @return an array with all tree nodes |
1499 | */ | |
1500 | function wiki_build_tree($page, $node, &$keys) { | |
1501 | $content = array(); | |
c3625f5b MG |
1502 | static $icon = null; |
1503 | if ($icon === null) { | |
317e98ba MG |
1504 | // Substitute the default navigation icon with empty image. |
1505 | $icon = new pix_icon('spacer', ''); | |
c3625f5b | 1506 | } |
00710f4c DC |
1507 | $pages = wiki_get_linked_pages($page->id); |
1508 | foreach ($pages as $p) { | |
1509 | $key = $page->id . ':' . $p->id; | |
1510 | if (in_array($key, $keys)) { | |
1511 | break; | |
1512 | } | |
1513 | array_push($keys, $key); | |
1514 | $l = wiki_parser_link($p); | |
1515 | $link = new moodle_url('/mod/wiki/view.php', array('pageid' => $p->id)); | |
4c4e6591 | 1516 | // navigation_node::get_content will format the title for us |
00710f4c DC |
1517 | $nodeaux = $node->add($p->title, $link, null, null, null, $icon); |
1518 | if ($l['new']) { | |
1519 | $nodeaux->add_class('wiki_newentry'); | |
1520 | } | |
1521 | wiki_build_tree($p, $nodeaux, $keys); | |
1522 | } | |
1523 | $content[] = $node; | |
1524 | return $content; | |
1525 | } | |
1526 | ||
1527 | /** | |
1528 | * Get linked pages from page | |
1529 | * @param int $pageid | |
1530 | */ | |
1531 | function wiki_get_linked_pages($pageid) { | |
1532 | global $DB; | |
1533 | ||
9730c555 | 1534 | $sql = "SELECT p.id, p.title |
e22465c7 PS |
1535 | FROM {wiki_pages} p |
1536 | JOIN {wiki_links} l ON l.topageid = p.id | |
9730c555 JP |
1537 | WHERE l.frompageid = ? |
1538 | ORDER BY p.title ASC"; | |
37dcd4b6 JP |
1539 | return $DB->get_records_sql($sql, array($pageid)); |
1540 | } | |
1541 | ||
1542 | /** | |
1543 | * Get updated pages from wiki | |
1544 | * @param int $pageid | |
1545 | */ | |
1546 | function wiki_get_updated_pages_by_subwiki($swid) { | |
1547 | global $DB, $USER; | |
1548 | ||
9730c555 JP |
1549 | $sql = "SELECT * |
1550 | FROM {wiki_pages} | |
1551 | WHERE subwikiid = ? AND timemodified > ? | |
1552 | ORDER BY timemodified DESC"; | |
37dcd4b6 | 1553 | return $DB->get_records_sql($sql, array($swid, $USER->lastlogin)); |
00710f4c | 1554 | } |
23cbaefb DP |
1555 | |
1556 | /** | |
1557 | * Check if the user can create pages in a certain wiki. | |
1558 | * @param context $context Wiki's context. | |
1559 | * @param integer|stdClass $user A user id or object. By default (null) checks the permissions of the current user. | |
1560 | * @return bool True if user can create pages, false otherwise. | |
1561 | * @since Moodle 3.1 | |
1562 | */ | |
1563 | function wiki_can_create_pages($context, $user = null) { | |
1564 | return has_capability('mod/wiki:createpage', $context, $user); | |
1565 | } | |
44f1b701 DP |
1566 | |
1567 | /** | |
1568 | * Get a sub wiki instance by wiki id, group id and user id. | |
1569 | * If the wiki doesn't exist in DB it will return an isntance with id -1. | |
1570 | * | |
1571 | * @param int $wikiid Wiki ID. | |
1572 | * @param int $groupid Group ID. | |
1573 | * @param int $userid User ID. | |
1574 | * @return object Subwiki instance. | |
1575 | * @since Moodle 3.1 | |
1576 | */ | |
1577 | function wiki_get_possible_subwiki_by_group($wikiid, $groupid, $userid = 0) { | |
1578 | if (!$subwiki = wiki_get_subwiki_by_group($wikiid, $groupid, $userid)) { | |
1579 | $subwiki = new stdClass(); | |
1580 | $subwiki->id = -1; | |
1581 | $subwiki->wikiid = $wikiid; | |
1582 | $subwiki->groupid = $groupid; | |
1583 | $subwiki->userid = $userid; | |
1584 | } | |
1585 | return $subwiki; | |
1586 | } | |
1587 | ||
1588 | /** | |
1589 | * Get all the possible subwikis visible to the user in a wiki. | |
1590 | * It will return all the subwikis that can be created in a wiki, even if they don't exist in DB yet. | |
1591 | * | |
1592 | * @param stdClass $wiki Wiki to get the subwikis from. | |
1593 | * @param cm_info|stdClass $cm Optional. The course module object. | |
1594 | * @param context_module $context Optional. Context of wiki module. | |
1595 | * @return array List of subwikis. | |
1596 | * @since Moodle 3.1 | |
1597 | */ | |
1598 | function wiki_get_visible_subwikis($wiki, $cm = null, $context = null) { | |
1599 | global $USER; | |
1600 | ||
1601 | $subwikis = array(); | |
1602 | ||
1603 | if (empty($wiki) or !is_object($wiki)) { | |
1604 | // Wiki not valid. | |
1605 | return $subwikis; | |
1606 | } | |
1607 | ||
1608 | if (empty($cm)) { | |
1609 | $cm = get_coursemodule_from_instance('wiki', $wiki->id); | |
1610 | } | |
1611 | if (empty($context)) { | |
1612 | $context = context_module::instance($cm->id); | |
1613 | } | |
1614 | ||
1615 | if (!has_capability('mod/wiki:viewpage', $context)) { | |
1616 | return $subwikis; | |
1617 | } | |
1618 | ||
1619 | $manage = has_capability('mod/wiki:managewiki', $context); | |
1620 | ||
1621 | if (!$groupmode = groups_get_activity_groupmode($cm)) { | |
1622 | // No groups. | |
1623 | if ($wiki->wikimode == 'collaborative') { | |
1624 | // Only 1 subwiki. | |
1625 | $subwikis[] = wiki_get_possible_subwiki_by_group($wiki->id, 0, 0); | |
1626 | } else if ($wiki->wikimode == 'individual') { | |
1627 | // There's 1 subwiki per user. | |
1628 | if ($manage) { | |
1629 | // User can view all subwikis. | |
1630 | $users = get_enrolled_users($context); | |
1631 | foreach ($users as $user) { | |
1632 | $subwikis[] = wiki_get_possible_subwiki_by_group($wiki->id, 0, $user->id); | |
1633 | } | |
1634 | } else { | |
1635 | // User can only see his subwiki. | |
1636 | $subwikis[] = wiki_get_possible_subwiki_by_group($wiki->id, 0, $USER->id); | |
1637 | } | |
1638 | } | |
1639 | } else { | |
1640 | if ($wiki->wikimode == 'collaborative') { | |
1641 | // 1 subwiki per group. | |
1642 | $aag = has_capability('moodle/site:accessallgroups', $context); | |
1643 | if ($aag || $groupmode == VISIBLEGROUPS) { | |
1644 | // User can see all groups. | |
1645 | $allowedgroups = groups_get_all_groups($cm->course, 0, $cm->groupingid); | |
1646 | $allparticipants = new stdClass(); | |
1647 | $allparticipants->id = 0; | |
1648 | array_unshift($allowedgroups, $allparticipants); // Add all participants. | |
1649 | } else { | |
1650 | // User can only see the groups he belongs to. | |
1651 | $allowedgroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid); | |
1652 | } | |
1653 | ||
1654 | foreach ($allowedgroups as $group) { | |
1655 | $subwikis[] = wiki_get_possible_subwiki_by_group($wiki->id, $group->id, 0); | |
1656 | } | |
1657 | } else if ($wiki->wikimode == 'individual') { | |
1658 | // 1 subwiki per user and group. | |
1659 | ||
1660 | if ($manage || $groupmode == VISIBLEGROUPS) { | |
1661 | // User can view all subwikis. | |
1662 | $users = get_enrolled_users($context); | |
1663 | foreach ($users as $user) { | |
1664 | // Get all the groups this user belongs to. | |
1665 | $groups = groups_get_all_groups($cm->course, $user->id); | |
1666 | if (!empty($groups)) { | |
1667 | foreach ($groups as $group) { | |
1668 | $subwikis[] = wiki_get_possible_subwiki_by_group($wiki->id, $group->id, $user->id); | |
1669 | } | |
1670 | } else { | |
1671 | // User doesn't belong to any group, add it to group 0. | |
1672 | $subwikis[] = wiki_get_possible_subwiki_by_group($wiki->id, 0, $user->id); | |
1673 | } | |
1674 | } | |
1675 | } else { | |
1676 | // The user can only see the subwikis of the groups he belongs. | |
1677 | $allowedgroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid); | |
1678 | foreach ($allowedgroups as $group) { | |
1679 | $users = groups_get_members($group->id); | |
1680 | foreach ($users as $user) { | |
1681 | $subwikis[] = wiki_get_possible_subwiki_by_group($wiki->id, $group->id, $user->id); | |
1682 | } | |
1683 | } | |
1684 | } | |
1685 | } | |
1686 | } | |
1687 | ||
1688 | return $subwikis; | |
1689 | } | |
62e20cfe DP |
1690 | |
1691 | /** | |
1692 | * Utility function for getting a subwiki by group and user, validating that the user can view it. | |
1693 | * If the subwiki doesn't exists in DB yet it'll have id -1. | |
1694 | * | |
1695 | * @param stdClass $wiki The wiki. | |
1696 | * @param int $groupid Group ID. 0 means the subwiki doesn't use groups. | |
1697 | * @param int $userid User ID. 0 means the subwiki doesn't use users. | |
1698 | * @return stdClass Subwiki. If it doesn't exists in DB yet it'll have id -1. If the user can't view the | |
1699 | * subwiki this function will return false. | |
1700 | * @since Moodle 3.1 | |
1701 | * @throws moodle_exception | |
1702 | */ | |
1703 | function wiki_get_subwiki_by_group_and_user_with_validation($wiki, $groupid, $userid) { | |
1704 | global $USER, $DB; | |
1705 | ||
1706 | // Get subwiki based on group and user. | |
1707 | if (!$subwiki = wiki_get_subwiki_by_group($wiki->id, $groupid, $userid)) { | |
1708 | ||
1709 | // The subwiki doesn't exist. | |
1710 | // Validate if user is valid. | |
1711 | if ($userid != 0) { | |
1712 | $user = core_user::get_user($userid, '*', MUST_EXIST); | |
1713 | core_user::require_active_user($user); | |
1714 | } | |
1715 | ||
1716 | // Validate that groupid is valid. | |
1717 | if ($groupid != 0 && !groups_group_exists($groupid)) { | |
1718 | throw new moodle_exception('cannotfindgroup', 'error'); | |
1719 | } | |
1720 | ||
1721 | // Valid data but subwiki not found. We'll simulate a subwiki object to check if the user would be able to see it | |
1722 | // if it existed. If he's able to see it then we'll return an empty array because the subwiki has no pages. | |
1723 | $subwiki = new stdClass(); | |
1724 | $subwiki->id = -1; | |
1725 | $subwiki->wikiid = $wiki->id; | |
1726 | $subwiki->userid = $userid; | |
1727 | $subwiki->groupid = $groupid; | |
1728 | } | |
1729 | ||
1730 | // Check that the user can view the subwiki. This function checks capabilities. | |
1731 | if (!wiki_user_can_view($subwiki, $wiki)) { | |
1732 | return false; | |
1733 | } | |
1734 | ||
1735 | return $subwiki; | |
1736 | } |