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 | * | |
21 | * @package mod-wiki-2.0 | |
22 | * @copyrigth 2009 Marc Alier, Jordi Piguillem marc.alier@upc.edu | |
23 | * @copyrigth 2009 Universitat Politecnica de Catalunya http://www.upc.edu | |
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'); | |
37 | ||
38 | define('WIKI_REFRESH_CACHE_TIME', 30); // @TODO: To be deleted. | |
39 | define('FORMAT_CREOLE', '37'); | |
40 | define('FORMAT_NWIKI', '38'); | |
41 | define('NO_VALID_RATE', '-999'); | |
42 | define('IMPROVEMENT', '+'); | |
43 | define('EQUAL', '='); | |
44 | define('WORST', '-'); | |
45 | ||
46 | define('LOCK_TIMEOUT', 30); | |
47 | ||
48 | /** | |
49 | * Get a wiki instance | |
50 | * @param int $wikiid the instance id of wiki | |
51 | */ | |
52 | function wiki_get_wiki($wikiid) { | |
53 | global $DB; | |
54 | ||
55 | return $DB->get_record('wiki', array('id' => $wikiid)); | |
56 | } | |
57 | ||
58 | /** | |
59 | * Get sub wiki instances with same wiki id | |
60 | * @param int $wikiid | |
61 | */ | |
62 | function wiki_get_subwikis($wikiid) { | |
63 | global $DB; | |
64 | return $DB->get_records('wiki_subwikis', array('wikiid' => $wikiid)); | |
65 | } | |
66 | ||
67 | /** | |
68 | * Get a sub wiki instance by wiki id and group id | |
69 | * @param int $wikiid | |
70 | * @param int $groupid | |
71 | * @return object | |
72 | */ | |
73 | function wiki_get_subwiki_by_group($wikiid, $groupid, $userid = 0) { | |
74 | global $DB; | |
75 | return $DB->get_record('wiki_subwikis', array('wikiid' => $wikiid, 'groupid' => $groupid, 'userid' => $userid)); | |
76 | } | |
77 | ||
78 | /** | |
79 | * Get a sub wiki instace by instance id | |
80 | * @param int $subwikiid | |
81 | * @return object | |
82 | */ | |
83 | function wiki_get_subwiki($subwikiid) { | |
84 | global $DB; | |
85 | return $DB->get_record('wiki_subwikis', array('id' => $subwikiid)); | |
86 | ||
87 | } | |
88 | ||
89 | /** | |
90 | * Add a new sub wiki instance | |
91 | * @param int $wikiid | |
92 | * @param int $groupid | |
93 | * @return int $insertid | |
94 | */ | |
95 | function wiki_add_subwiki($wikiid, $groupid, $userid = 0) { | |
96 | global $DB; | |
97 | ||
98 | $record = new StdClass(); | |
99 | $record->wikiid = $wikiid; | |
100 | $record->groupid = $groupid; | |
101 | $record->userid = $userid; | |
102 | ||
103 | $insertid = $DB->insert_record('wiki_subwikis', $record); | |
104 | return $insertid; | |
105 | } | |
106 | ||
107 | /** | |
108 | * Get a wiki instance by pageid | |
109 | * @param int $pageid | |
110 | * @return object | |
111 | */ | |
112 | function wiki_get_wiki_from_pageid($pageid) { | |
113 | global $DB; | |
114 | ||
9730c555 JP |
115 | $sql = "SELECT w.* |
116 | FROM {wiki} w, {wiki_subwikis} s, {wiki_pages} p | |
117 | WHERE p.id = ? AND | |
118 | p.subwikiid = s.id AND | |
119 | s.wikiid = w.id"; | |
00710f4c DC |
120 | |
121 | return $DB->get_record_sql($sql, array($pageid)); | |
122 | } | |
123 | ||
124 | /** | |
125 | * Get a wiki page by pageid | |
126 | * @param int $pageid | |
127 | * @return object | |
128 | */ | |
129 | function wiki_get_page($pageid) { | |
130 | global $DB; | |
131 | return $DB->get_record('wiki_pages', array('id' => $pageid)); | |
132 | } | |
133 | ||
134 | /** | |
135 | * Get latest version of wiki page | |
136 | * @param int $pageid | |
137 | * @return object | |
138 | */ | |
139 | function wiki_get_current_version($pageid) { | |
140 | global $DB; | |
141 | ||
9730c555 JP |
142 | // @TODO: Fix this query |
143 | $sql = "SELECT * | |
144 | FROM {wiki_versions} | |
145 | WHERE pageid = ? | |
70b082fa AB |
146 | ORDER BY version DESC"; |
147 | return array_pop($DB->get_records_sql($sql, array($pageid), 0, 1)); | |
00710f4c DC |
148 | |
149 | } | |
150 | ||
151 | /** | |
152 | * Alias of wiki_get_current_version | |
153 | * @TODO, does the exactly same thing as wiki_get_current_version, should be removed | |
154 | * @param int $pageid | |
155 | * @return object | |
156 | */ | |
157 | function wiki_get_last_version($pageid) { | |
158 | return wiki_get_current_version($pageid); | |
159 | } | |
160 | ||
161 | /** | |
162 | * Get page section | |
163 | * @param int $pageid | |
164 | * @param string $section | |
165 | */ | |
166 | function wiki_get_section_page($page, $section) { | |
167 | ||
168 | $version = wiki_get_current_version($page->id); | |
169 | return wiki_parser_proxy::get_section($version->content, $version->contentformat, $section); | |
170 | } | |
171 | ||
172 | /** | |
173 | * Get a wiki page by page title | |
174 | * @param int $swid, sub wiki id | |
175 | * @param string $title | |
176 | * @return object | |
177 | */ | |
178 | function wiki_get_page_by_title($swid, $title) { | |
179 | global $DB; | |
180 | return $DB->get_record('wiki_pages', array('subwikiid' => $swid, 'title' => $title)); | |
181 | } | |
182 | ||
183 | /** | |
184 | * Get a version record by record id | |
185 | * @param int $versionid, the version id | |
186 | * @return object | |
187 | */ | |
188 | function wiki_get_version($versionid) { | |
189 | global $DB; | |
190 | return $DB->get_record('wiki_versions', array('id' => $versionid)); | |
191 | } | |
192 | ||
193 | /** | |
194 | * Get first page of wiki instace | |
195 | * @param int $subwikiid | |
196 | * @param int $module, wiki instance object | |
197 | */ | |
37dcd4b6 | 198 | function wiki_get_first_page($subwikid, $module = null) { |
00710f4c | 199 | global $DB, $USER; |
00710f4c | 200 | |
9730c555 JP |
201 | $sql = "SELECT p.* |
202 | FROM {wiki} w, {wiki_subwikis} s, {wiki_pages} p | |
203 | WHERE s.id = ? AND | |
204 | s.wikiid = w.id AND | |
205 | w.firstpagetitle = p.title AND | |
206 | p.subwikiid = s.id"; | |
00710f4c DC |
207 | return $DB->get_record_sql($sql, array($subwikid)); |
208 | } | |
209 | ||
210 | function wiki_save_section($wikipage, $sectiontitle, $sectioncontent, $userid) { | |
211 | ||
212 | $wiki = wiki_get_wiki_from_pageid($wikipage->id); | |
213 | $cm = get_coursemodule_from_instance('wiki', $wiki->id); | |
214 | $context = get_context_instance(CONTEXT_MODULE, $cm->id); | |
215 | ||
216 | if (has_capability('mod/wiki:editpage', $context)) { | |
217 | $version = wiki_get_current_version($wikipage->id); | |
218 | $content = wiki_parser_proxy::get_section($version->content, $version->contentformat, $sectiontitle, true); | |
219 | ||
220 | $newcontent = $content[0] . $sectioncontent . $content[2]; | |
221 | ||
222 | return wiki_save_page($wikipage, $newcontent, $userid); | |
223 | } else { | |
224 | return false; | |
225 | } | |
226 | } | |
227 | ||
228 | /** | |
229 | * Save page content | |
230 | * @param object $wikipage | |
231 | * @param string $newcontent | |
232 | * @param int $userid | |
233 | */ | |
234 | function wiki_save_page($wikipage, $newcontent, $userid) { | |
235 | global $DB; | |
236 | ||
237 | $wiki = wiki_get_wiki_from_pageid($wikipage->id); | |
238 | $cm = get_coursemodule_from_instance('wiki', $wiki->id); | |
239 | $context = get_context_instance(CONTEXT_MODULE, $cm->id); | |
240 | ||
241 | if (has_capability('mod/wiki:editpage', $context)) { | |
242 | $version = wiki_get_current_version($wikipage->id); | |
243 | ||
244 | $version->content = $newcontent; | |
245 | $version->userid = $userid; | |
246 | $version->version++; | |
247 | $version->timecreated = time(); | |
a9637e7d | 248 | $versionid = $DB->insert_record('wiki_versions', $version); |
00710f4c DC |
249 | |
250 | $wikipage->timemodified = $version->timecreated; | |
251 | $wikipage->userid = $userid; | |
252 | $return = wiki_refresh_cachedcontent($wikipage, $newcontent); | |
253 | ||
254 | return $return; | |
255 | } else { | |
256 | return false; | |
257 | } | |
258 | } | |
259 | ||
260 | function wiki_refresh_cachedcontent($page, $newcontent = null) { | |
261 | global $DB; | |
262 | ||
263 | $version = wiki_get_current_version($page->id); | |
264 | if (!isset($newcontent)) { | |
265 | $newcontent = $version->content; | |
266 | } | |
267 | ||
268 | $options = array('swid' => $page->subwikiid, 'pageid' => $page->id); | |
269 | $parseroutput = wiki_parse_content($version->contentformat, $newcontent, $options); | |
270 | $page->cachedcontent = $parseroutput['toc'] . $parseroutput['parsed_text']; | |
271 | $page->timerendered = time(); | |
272 | $DB->update_record('wiki_pages', $page); | |
273 | ||
274 | wiki_refresh_page_links($page, $parseroutput['link_count']); | |
275 | ||
276 | return array('page' => $page, 'sections' => $parseroutput['repeated_sections'], 'version' => $version->version); | |
277 | } | |
278 | /** | |
279 | * Restore a page | |
280 | */ | |
281 | function wiki_restore_page($wikipage, $newcontent, $userid) { | |
282 | $return = wiki_save_page($wikipage, $newcontent, $userid); | |
283 | return $return['page']; | |
284 | } | |
285 | ||
286 | function wiki_refresh_page_links($page, $links) { | |
287 | global $DB; | |
288 | ||
289 | $DB->delete_records('wiki_links', array('frompageid' => $page->id)); | |
290 | foreach ($links as $linkname => $linkinfo) { | |
291 | ||
292 | $newlink = new stdClass(); | |
293 | $newlink->subwikiid = $page->subwikiid; | |
294 | $newlink->frompageid = $page->id; | |
295 | ||
296 | if ($linkinfo['new']) { | |
297 | $newlink->tomissingpage = $linkname; | |
298 | } else { | |
299 | $newlink->topageid = $linkinfo['pageid']; | |
300 | } | |
301 | ||
90c42e0f | 302 | $DB->insert_record('wiki_links', $newlink); |
00710f4c DC |
303 | |
304 | } | |
305 | } | |
306 | ||
307 | /** | |
308 | * Create a new wiki page, if the page exists, return existing pageid | |
309 | * @param int $swid | |
310 | * @param string $title | |
311 | * @param string $format | |
312 | * @param int $userid | |
313 | */ | |
314 | function wiki_create_page($swid, $title, $format, $userid) { | |
3b5e2acb | 315 | global $DB, $PAGE; |
7bc03dd5 JP |
316 | $subwiki = wiki_get_subwiki($swid); |
317 | $cm = get_coursemodule_from_instance('wiki', $subwiki->wikiid); | |
318 | $context = get_context_instance(CONTEXT_MODULE, $cm->id); | |
319 | require_capability('mod/wiki:editpage', $context); | |
00710f4c DC |
320 | // if page exists |
321 | if ($page = wiki_get_page_by_title($swid, $title)) { | |
322 | return $page->id; | |
323 | } | |
324 | ||
325 | // Creating a new empty version | |
326 | $version = new stdClass(); | |
327 | $version->content = ''; | |
328 | $version->contentformat = $format; | |
329 | $version->version = 0; | |
330 | $version->timecreated = time(); | |
331 | $version->userid = $userid; | |
332 | ||
333 | $versionid = null; | |
a9637e7d | 334 | $versionid = $DB->insert_record('wiki_versions', $version); |
00710f4c DC |
335 | |
336 | // Createing a new empty page | |
337 | $page = new stdClass(); | |
338 | $page->subwikiid = $swid; | |
339 | $page->title = $title; | |
340 | $page->cachedcontent = ''; | |
341 | $page->timecreated = $version->timecreated; | |
342 | $page->timemodified = $version->timecreated; | |
343 | $page->timerendered = $version->timecreated; | |
344 | $page->userid = $userid; | |
345 | $page->pageviews = 0; | |
346 | $page->readonly = 0; | |
347 | ||
348 | $pageid = $DB->insert_record('wiki_pages', $page); | |
349 | ||
350 | // Setting the pageid | |
351 | $version->id = $versionid; | |
352 | $version->pageid = $pageid; | |
353 | $DB->update_record('wiki_versions', $version); | |
354 | ||
355 | wiki_make_cache_expire($page->title); | |
356 | return $pageid; | |
357 | } | |
358 | ||
359 | function wiki_make_cache_expire($pagename) { | |
360 | global $DB; | |
361 | ||
9730c555 JP |
362 | $sql = "UPDATE {wiki_pages} |
363 | SET timerendered = 0 | |
364 | WHERE id IN ( SELECT l.frompageid | |
365 | FROM {wiki_links} l | |
366 | WHERE l.tomissingpage = ? | |
367 | )"; | |
00710f4c DC |
368 | $DB->execute ($sql, array($pagename)); |
369 | } | |
370 | ||
371 | /** | |
372 | * Get a specific version of page | |
373 | * @param int $pageid | |
374 | * @param int $version | |
375 | */ | |
376 | function wiki_get_wiki_page_version($pageid, $version) { | |
377 | global $DB; | |
378 | return $DB->get_record('wiki_versions', array('pageid' => $pageid, 'version' => $version)); | |
379 | } | |
380 | ||
381 | /** | |
382 | * Get version list | |
383 | * @param int $pageid | |
384 | * @param int $limitfrom | |
385 | * @param int $limitnum | |
386 | */ | |
387 | function wiki_get_wiki_page_versions($pageid, $limitfrom, $limitnum) { | |
388 | global $DB; | |
389 | return $DB->get_records('wiki_versions', array('pageid' => $pageid), 'version DESC', '*', $limitfrom, $limitnum); | |
390 | } | |
391 | ||
392 | /** | |
393 | * Count the number of page version | |
394 | * @param int $pageid | |
395 | */ | |
396 | function wiki_count_wiki_page_versions($pageid) { | |
397 | global $DB; | |
398 | return $DB->count_records('wiki_versions', array('pageid' => $pageid)); | |
399 | } | |
400 | ||
401 | /** | |
402 | * Get linked from page | |
403 | * @param int $pageid | |
404 | */ | |
405 | function wiki_get_linked_to_pages($pageid) { | |
406 | global $DB; | |
407 | return $DB->get_records('wiki_links', array('frompageid' => $pageid)); | |
408 | } | |
409 | ||
410 | /** | |
411 | * Get linked from page | |
412 | * @param int $pageid | |
413 | */ | |
414 | function wiki_get_linked_from_pages($pageid) { | |
415 | global $DB; | |
416 | return $DB->get_records('wiki_links', array('topageid' => $pageid)); | |
417 | } | |
418 | ||
419 | /** | |
420 | * Get pages which user have been edited | |
421 | * @param int $swid | |
422 | * @param int $userid | |
423 | */ | |
424 | function wiki_get_contributions($swid, $userid) { | |
425 | global $DB; | |
426 | ||
9730c555 JP |
427 | $sql = "SELECT v.* |
428 | FROM {wiki_versions} v, {wiki_pages} p | |
429 | WHERE p.subwikiid = ? AND | |
430 | v.pageid = p.id AND | |
431 | v.userid = ?"; | |
00710f4c DC |
432 | |
433 | return $DB->get_records_sql($sql, array($swid, $userid)); | |
434 | } | |
435 | ||
436 | /** | |
437 | * Get missing or empty pages in wiki | |
438 | * @param int $swid sub wiki id | |
439 | */ | |
440 | function wiki_get_missing_or_empty_pages($swid) { | |
441 | global $DB; | |
442 | ||
9730c555 JP |
443 | $sql = "SELECT DISTINCT p.title, p.id, p.subwikiid |
444 | FROM {wiki} w, {wiki_subwikis} s, {wiki_pages} p | |
445 | WHERE s.wikiid = w.id and | |
446 | s.id = ? and | |
447 | w.firstpagetitle != p.title and | |
448 | p.subwikiid = ? and | |
449 | 1 = (SELECT count(*) | |
450 | FROM {wiki_versions} v | |
451 | WHERE v.pageid = p.id) | |
452 | UNION | |
453 | SELECT DISTINCT l.tomissingpage as title, 0 as id, l.subwikiid | |
454 | FROM {wiki_links} l | |
455 | WHERE l.subwikiid = ? and | |
456 | l.topageid = 0"; | |
00710f4c DC |
457 | |
458 | return $DB->get_records_sql($sql, array($swid, $swid, $swid)); | |
459 | } | |
460 | ||
461 | /** | |
462 | * Get pages list in wiki | |
463 | * @param int $swid sub wiki id | |
464 | */ | |
465 | function wiki_get_page_list($swid) { | |
466 | global $DB; | |
467 | $records = $DB->get_records('wiki_pages', array('subwikiid' => $swid), 'title ASC'); | |
468 | return $records; | |
469 | } | |
470 | ||
471 | /** | |
472 | * Return a list of orphaned wikis for one specific subwiki | |
473 | * @global object | |
474 | * @param int $swid sub wiki id | |
475 | */ | |
476 | function wiki_get_orphaned_pages($swid) { | |
477 | global $DB; | |
478 | ||
9730c555 JP |
479 | $sql = "SELECT p.id, p.title |
480 | FROM {wiki_pages} p, {wiki} w , {wiki_subwikis} s | |
481 | WHERE p.subwikiid = ? | |
482 | AND s.id = ? | |
483 | AND w.id = s.wikiid | |
484 | AND p.title != w.firstpagetitle | |
485 | AND p.id NOT IN (SELECT topageid FROM {wiki_links} WHERE subwikiid = ?);"; | |
00710f4c | 486 | |
9730c555 | 487 | return $DB->get_records_sql($sql, array($swid, $swid, $swid)); |
00710f4c DC |
488 | } |
489 | ||
490 | /** | |
491 | * Search wiki title | |
492 | * @param int $swid sub wiki id | |
493 | * @param string $search | |
494 | */ | |
495 | function wiki_search_title($swid, $search) { | |
496 | global $DB; | |
75b986e7 JP |
497 | |
498 | return $DB->get_records_select('wiki_pages', "subwikiid = ? AND title LIKE ?", array($swid, '%'.$search.'%')); | |
00710f4c DC |
499 | } |
500 | ||
501 | /** | |
502 | * Search wiki content | |
503 | * @param int $swid sub wiki id | |
504 | * @param string $search | |
505 | */ | |
506 | function wiki_search_content($swid, $search) { | |
507 | global $DB; | |
75b986e7 JP |
508 | |
509 | return $DB->get_records_select('wiki_pages', "subwikiid = ? AND cachedcontent LIKE ?", array($swid, '%'.$search.'%')); | |
00710f4c DC |
510 | } |
511 | ||
512 | /** | |
513 | * Search wiki title and content | |
514 | * @param int $swid sub wiki id | |
515 | * @param string $search | |
516 | */ | |
517 | function wiki_search_all($swid, $search) { | |
518 | global $DB; | |
75b986e7 JP |
519 | |
520 | return $DB->get_records_select('wiki_pages', "subwikiid = ? AND (cachedcontent LIKE ? OR title LIKE ?)", array($swid, '%'.$search.'%', '%'.$search.'%')); | |
00710f4c DC |
521 | } |
522 | ||
523 | /** | |
9ffd2726 | 524 | * Get user data |
00710f4c DC |
525 | */ |
526 | function wiki_get_user_info($userid) { | |
9ffd2726 JP |
527 | global $DB; |
528 | return $DB->get_record('user', array('id' => $userid)); | |
00710f4c DC |
529 | } |
530 | ||
531 | /** | |
532 | * Increase page view nubmer | |
533 | * @param int $page, database record | |
534 | */ | |
535 | function wiki_increment_pageviews($page) { | |
536 | global $DB; | |
537 | ||
538 | $page->pageviews++; | |
539 | $DB->update_record('wiki_pages', $page); | |
540 | } | |
541 | ||
542 | //---------------------------------------------------------- | |
543 | //---------------------------------------------------------- | |
544 | ||
545 | /** | |
546 | * Text format supported by wiki module | |
547 | */ | |
548 | function wiki_get_formats() { | |
44c0751b | 549 | return array('html', 'creole', 'nwiki'); |
00710f4c DC |
550 | } |
551 | ||
552 | /** | |
553 | * Parses a string with the wiki markup language in $markup. | |
554 | * | |
555 | * @return Array or false when something wrong has happened. | |
556 | * | |
557 | * Returned array contains the following fields: | |
558 | * 'parsed_text' => String. Contains the parsed wiki content. | |
559 | * 'unparsed_text' => String. Constains the original wiki content. | |
560 | * 'link_count' => Array of array('destination' => ..., 'new' => "is new?"). Contains the internal wiki links found in the wiki content. | |
561 | * 'deleted_sections' => the list of deleted sections. | |
562 | * '' => | |
563 | * | |
564 | * @author Josep Arús Pous | |
565 | **/ | |
566 | function wiki_parse_content($markup, $pagecontent, $options = array()) { | |
567 | global $PAGE; | |
568 | ||
569 | $subwiki = wiki_get_subwiki($options['swid']); | |
570 | $cm = get_coursemodule_from_instance("wiki", $subwiki->wikiid); | |
571 | $context = get_context_instance(CONTEXT_MODULE, $cm->id); | |
572 | ||
64f93798 | 573 | $parser_options = array('link_callback' => '/mod/wiki/locallib.php:wiki_parser_link', 'link_callback_args' => array('swid' => $options['swid']), 'table_callback' => '/mod/wiki/locallib.php:wiki_parser_table', 'real_path_callback' => '/mod/wiki/locallib.php:wiki_parser_real_path', 'real_path_callback_args' => array('context' => $context, 'component' => 'mod_wiki', 'filearea' => 'attachments', 'pageid' => $options['pageid']), 'pageid' => $options['pageid'], 'pretty_print' => (isset($options['pretty_print']) && $options['pretty_print']), 'printable' => (isset($options['printable']) && $options['printable'])); |
00710f4c DC |
574 | |
575 | return wiki_parser_proxy::parse($pagecontent, $markup, $parser_options); | |
576 | } | |
577 | ||
578 | /** | |
579 | * This function is the parser callback to parse wiki links. | |
580 | * | |
581 | * It returns the necesary information to print a link. | |
582 | * | |
583 | * NOTE: Empty pages and non-existent pages must be print in red color. | |
584 | * | |
585 | * @param link name of a page | |
586 | * @param $options | |
587 | * | |
588 | * @return | |
589 | * | |
590 | * @TODO Doc return and options | |
591 | */ | |
592 | function wiki_parser_link($link, $options = null) { | |
593 | global $CFG; | |
594 | ||
595 | if (is_object($link)) { | |
596 | $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)); | |
597 | ||
598 | $version = wiki_get_current_version($link->id); | |
599 | if ($version->version == 0) { | |
600 | $parsedlink['new'] = true; | |
601 | } | |
602 | return $parsedlink; | |
603 | } else { | |
604 | $swid = $options['swid']; | |
605 | ||
606 | if ($page = wiki_get_page_by_title($swid, $link)) { | |
607 | $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)); | |
608 | ||
609 | $version = wiki_get_current_version($page->id); | |
610 | if ($version->version == 0) { | |
611 | $parsedlink['new'] = true; | |
612 | } | |
613 | ||
614 | return $parsedlink; | |
615 | ||
616 | } else { | |
617 | 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)); | |
618 | } | |
619 | } | |
620 | } | |
621 | ||
622 | /** | |
623 | * Returns the table fully parsed (HTML) | |
624 | * | |
625 | * @return HTML for the table $table | |
626 | * @author Josep Arús Pous | |
627 | * | |
628 | **/ | |
629 | function wiki_parser_table($table) { | |
630 | global $OUTPUT; | |
631 | ||
632 | $htmltable = new html_table(); | |
633 | ||
634 | $headers = $table[0]; | |
635 | $htmltable->head = array(); | |
636 | foreach ($headers as $h) { | |
637 | $htmltable->head[] = $h[1]; | |
638 | } | |
639 | ||
640 | array_shift($table); | |
641 | $htmltable->data = array(); | |
642 | foreach ($table as $row) { | |
643 | $row_data = array(); | |
644 | foreach ($row as $r) { | |
645 | $row_data[] = $r[1]; | |
646 | } | |
647 | $htmltable->data[] = $row_data; | |
648 | } | |
649 | ||
650 | return html_writer::table($htmltable); | |
651 | } | |
652 | ||
653 | /** | |
654 | * Returns an absolute path link, unless there is no such link. | |
655 | * | |
44d8a940 PS |
656 | * @param string url Link's URL |
657 | * @param stdClass context filearea params | |
658 | * @param string filearea | |
659 | * @param int fileareaid | |
00710f4c DC |
660 | * |
661 | * @return File full path | |
662 | */ | |
663 | ||
664 | function wiki_parser_real_path($url, $context, $filearea, $fileareaid) { | |
665 | global $CFG; | |
666 | ||
667 | if (preg_match("/^(?:http|ftp)s?\:\/\//", $url)) { | |
668 | return $url; | |
669 | } else { | |
670 | return "{$CFG->wwwroot}/pluginfile.php/{$context->id}/$filearea/$fileareaid/$url"; | |
671 | } | |
672 | } | |
673 | ||
674 | /** | |
675 | * Returns the token used by a wiki language to represent a given tag or "object" (bold -> **) | |
676 | * | |
677 | * @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. | |
678 | * @author Josep Arús Pous | |
679 | **/ | |
680 | function wiki_parser_get_token($markup, $name) { | |
681 | ||
682 | return wiki_parser_proxy::get_token($name, $markup); | |
683 | } | |
684 | ||
685 | /** | |
686 | * Checks if current user can view a subwiki | |
687 | * | |
688 | * @param $subwiki | |
689 | */ | |
690 | function wiki_user_can_view($subwiki) { | |
691 | global $USER; | |
692 | ||
693 | $wiki = wiki_get_wiki($subwiki->wikiid); | |
694 | $cm = get_coursemodule_from_instance('wiki', $wiki->id); | |
695 | $context = get_context_instance(CONTEXT_MODULE, $cm->id); | |
696 | ||
697 | // Working depending on activity groupmode | |
698 | switch (groups_get_activity_groupmode($cm)) { | |
699 | case NOGROUPS: | |
700 | ||
701 | if ($wiki->wikimode == 'collaborative') { | |
702 | // Collaborative Mode: | |
703 | // There is one wiki for all the class. | |
704 | // | |
705 | // Only view capbility needed | |
cece1791 | 706 | return has_capability('mod/wiki:viewpage', $context); |
00710f4c DC |
707 | } else if ($wiki->wikimode == 'individual') { |
708 | // Individual Mode: | |
709 | // Each person owns a wiki. | |
710 | if ($subwiki->userid == $USER->id) { | |
711 | // Only the owner of the wiki can view it | |
cece1791 | 712 | return has_capability('mod/wiki:viewpage', $context); |
00710f4c DC |
713 | } else { // User has special capabilities |
714 | // User must have: | |
715 | // mod/wiki:viewpage capability | |
716 | // and | |
717 | // mod/wiki:managewiki capability | |
cece1791 DC |
718 | $view = has_capability('mod/wiki:viewpage', $context); |
719 | $manage = has_capability('mod/wiki:managewiki', $context); | |
00710f4c DC |
720 | |
721 | return $view && $manage; | |
722 | } | |
723 | } else { | |
724 | //Error | |
725 | return false; | |
726 | } | |
727 | case SEPARATEGROUPS: | |
728 | // Collaborative and Individual Mode | |
729 | // | |
730 | // Collaborative Mode: | |
731 | // There is one wiki per group. | |
732 | // Individual Mode: | |
733 | // Each person owns a wiki. | |
734 | if ($wiki->wikimode == 'collaborative' || $wiki->wikimode == 'individual') { | |
735 | // Only members of subwiki group could view that wiki | |
736 | if ($subwiki->groupid == groups_get_activity_group($cm)) { | |
737 | // Only view capability needed | |
cece1791 | 738 | return has_capability('mod/wiki:viewpage', $context); |
00710f4c DC |
739 | |
740 | } else { // User is not part of that group | |
741 | // User must have: | |
742 | // mod/wiki:managewiki capability | |
743 | // or | |
744 | // moodle/site:accessallgroups capability | |
745 | // and | |
746 | // mod/wiki:viewpage capability | |
cece1791 DC |
747 | $view = has_capability('mod/wiki:viewpage', $context); |
748 | $manage = has_capability('mod/wiki:managewiki', $context); | |
749 | $access = has_capability('moodle/site:accessallgroups', $context); | |
00710f4c | 750 | return ($manage || $access) && $view; |
37dcd4b6 | 751 | } |
00710f4c DC |
752 | } else { |
753 | //Error | |
754 | return false; | |
755 | } | |
756 | case VISIBLEGROUPS: | |
757 | // Collaborative and Individual Mode | |
758 | // | |
759 | // Collaborative Mode: | |
760 | // There is one wiki per group. | |
761 | // Individual Mode: | |
762 | // Each person owns a wiki. | |
763 | if ($wiki->wikimode == 'collaborative' || $wiki->wikimode == 'individual') { | |
764 | // Everybody can read all wikis | |
765 | // | |
766 | // Only view capability needed | |
cece1791 | 767 | return has_capability('mod/wiki:viewpage', $context); |
00710f4c DC |
768 | } else { |
769 | //Error | |
770 | return false; | |
771 | } | |
772 | default: // Error | |
773 | return false; | |
774 | } | |
775 | } | |
776 | ||
777 | /** | |
778 | * Checks if current user can edit a subwiki | |
779 | * | |
780 | * @param $subwiki | |
781 | */ | |
782 | function wiki_user_can_edit($subwiki) { | |
783 | global $USER; | |
784 | ||
785 | $wiki = wiki_get_wiki($subwiki->wikiid); | |
786 | $cm = get_coursemodule_from_instance('wiki', $wiki->id); | |
787 | $context = get_context_instance(CONTEXT_MODULE, $cm->id); | |
788 | ||
789 | // Working depending on activity groupmode | |
790 | switch (groups_get_activity_groupmode($cm)) { | |
791 | case NOGROUPS: | |
792 | ||
793 | if ($wiki->wikimode == 'collaborative') { | |
794 | // Collaborative Mode: | |
795 | // There is a wiki for all the class. | |
796 | // | |
797 | // Only edit capbility needed | |
cece1791 | 798 | return has_capability('mod/wiki:editpage', $context); |
00710f4c DC |
799 | } else if ($wiki->wikimode == 'individual') { |
800 | // Individual Mode | |
801 | // There is a wiki per user | |
802 | ||
803 | // Only the owner of that wiki can edit it | |
804 | if ($subwiki->userid == $USER->id) { | |
cece1791 | 805 | return has_capability('mod/wiki:editpage', $context); |
00710f4c DC |
806 | } else { // Current user is not the owner of that wiki. |
807 | ||
808 | // User must have: | |
809 | // mod/wiki:editpage capability | |
810 | // and | |
811 | // mod/wiki:managewiki capability | |
cece1791 DC |
812 | $edit = has_capability('mod/wiki:editpage', $context); |
813 | $manage = has_capability('mod/wiki:managewiki', $context); | |
00710f4c DC |
814 | |
815 | return $edit && $manage; | |
816 | } | |
817 | } else { | |
818 | //Error | |
819 | return false; | |
820 | } | |
821 | case SEPARATEGROUPS: | |
822 | if ($wiki->wikimode == 'collaborative') { | |
823 | // Collaborative Mode: | |
824 | // There is one wiki per group. | |
825 | // | |
826 | // Only members of subwiki group could edit that wiki | |
827 | if ($subwiki->groupid == groups_get_activity_group($cm)) { | |
828 | // Only edit capability needed | |
cece1791 | 829 | return has_capability('mod/wiki:editpage', $context); |
00710f4c DC |
830 | } else { // User is not part of that group |
831 | // User must have: | |
832 | // mod/wiki:managewiki capability | |
833 | // and | |
834 | // moodle/site:accessallgroups capability | |
835 | // and | |
836 | // mod/wiki:editpage capability | |
cece1791 DC |
837 | $manage = has_capability('mod/wiki:managewiki', $context); |
838 | $access = has_capability('moodle/site:accessallgroups', $context); | |
839 | $edit = has_capability('mod/wiki:editpage', $context); | |
00710f4c DC |
840 | return $manage && $access && $edit; |
841 | } | |
842 | } else if ($wiki->wikimode == 'individual') { | |
843 | // Individual Mode: | |
844 | // Each person owns a wiki. | |
845 | // | |
846 | // Only the owner of that wiki can edit it | |
847 | if ($subwiki->userid == $USER->id) { | |
cece1791 | 848 | return has_capability('mod/wiki:editpage', $context); |
00710f4c DC |
849 | } else { // Current user is not the owner of that wiki. |
850 | // User must have: | |
851 | // mod/wiki:managewiki capability | |
852 | // and | |
853 | // moodle/site:accessallgroups capability | |
854 | // and | |
855 | // mod/wiki:editpage capability | |
cece1791 DC |
856 | $manage = has_capability('mod/wiki:managewiki', $context); |
857 | $access = has_capability('moodle/site:accessallgroups', $context); | |
858 | $edit = has_capability('mod/wiki:editpage', $context); | |
00710f4c DC |
859 | return $manage && $access && $edit; |
860 | } | |
861 | } else { | |
862 | //Error | |
863 | return false; | |
864 | } | |
865 | case VISIBLEGROUPS: | |
866 | if ($wiki->wikimode == 'collaborative') { | |
867 | // Collaborative Mode: | |
868 | // There is one wiki per group. | |
869 | // | |
870 | // Only members of subwiki group could edit that wiki | |
871 | if ($subwiki->groupid == groups_get_activity_group($cm)) { | |
872 | // Only edit capability needed | |
cece1791 | 873 | return has_capability('mod/wiki:editpage', $context); |
00710f4c DC |
874 | } else { // User is not part of that group |
875 | // User must have: | |
876 | // mod/wiki:managewiki capability | |
877 | // and | |
878 | // mod/wiki:editpage capability | |
cece1791 DC |
879 | $manage = has_capability('mod/wiki:managewiki', $context); |
880 | $edit = has_capability('mod/wiki:editpage', $context); | |
00710f4c DC |
881 | return $manage && $edit; |
882 | } | |
883 | } else if ($wiki->wikimode == 'individual') { | |
884 | // Individual Mode: | |
885 | // Each person owns a wiki. | |
886 | // | |
887 | // Only the owner of that wiki can edit it | |
888 | if ($subwiki->userid == $USER->id) { | |
cece1791 | 889 | return has_capability('mod/wiki:editpage', $context); |
00710f4c DC |
890 | } else { // Current user is not the owner of that wiki. |
891 | // User must have: | |
892 | // mod/wiki:managewiki capability | |
893 | // and | |
894 | // mod/wiki:editpage capability | |
cece1791 DC |
895 | $manage = has_capability('mod/wiki:managewiki', $context); |
896 | $edit = has_capability('mod/wiki:editpage', $context); | |
00710f4c DC |
897 | return $manage && $edit; |
898 | } | |
899 | } else { | |
900 | //Error | |
901 | return false; | |
902 | } | |
903 | default: // Error | |
904 | return false; | |
905 | } | |
906 | } | |
907 | ||
908 | //---------------- | |
909 | // Locks | |
910 | //---------------- | |
911 | ||
912 | /** | |
913 | * Checks if a page-section is locked. | |
914 | * | |
915 | * @return true if the combination of section and page is locked, FALSE otherwise. | |
916 | */ | |
917 | function wiki_is_page_section_locked($pageid, $userid, $section = null) { | |
918 | global $DB; | |
919 | ||
920 | $sql = "pageid = ? AND lockedat > ? AND userid != ?"; | |
921 | $params = array($pageid, time(), $userid); | |
922 | ||
923 | if (!empty($section)) { | |
924 | $sql .= " AND (sectionname = ? OR sectionname IS null)"; | |
925 | $params[] = $section; | |
926 | } | |
927 | ||
928 | return $DB->record_exists_select('wiki_locks', $sql, $params); | |
929 | } | |
930 | ||
931 | /** | |
932 | * Inserts or updates a wiki_locks record. | |
933 | */ | |
934 | function wiki_set_lock($pageid, $userid, $section = null, $insert = false) { | |
935 | global $DB; | |
936 | ||
937 | if (wiki_is_page_section_locked($pageid, $userid, $section)) { | |
938 | return false; | |
939 | } | |
940 | ||
941 | $params = array('pageid' => $pageid, 'userid' => $userid, 'sectionname' => $section); | |
942 | ||
943 | $lock = $DB->get_record('wiki_locks', $params); | |
944 | ||
945 | if (!empty($lock)) { | |
946 | $DB->update_record('wiki_locks', array('id' => $lock->id, 'lockedat' => time() + LOCK_TIMEOUT)); | |
947 | } else if ($insert) { | |
948 | $DB->insert_record('wiki_locks', array('pageid' => $pageid, 'sectionname' => $section, 'userid' => $userid, 'lockedat' => time() + 30)); | |
949 | } | |
950 | ||
951 | return true; | |
952 | } | |
953 | ||
954 | /** | |
955 | * 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. | |
956 | */ | |
957 | function wiki_delete_locks($pageid, $userid = null, $section = null, $delete_from_db = true, $delete_section_and_page = false) { | |
958 | global $DB; | |
959 | ||
960 | $params = array('pageid' => $pageid); | |
961 | ||
962 | if (!empty($userid)) { | |
963 | $params['userid'] = $userid; | |
964 | } | |
965 | ||
966 | if (!empty($section)) { | |
967 | $params['sectionname'] = $section; | |
968 | } | |
969 | ||
970 | if ($delete_from_db) { | |
971 | $DB->delete_records('wiki_locks', $params); | |
972 | if ($delete_section_and_page && !empty($section)) { | |
973 | $params['sectionname'] = null; | |
974 | $DB->delete_records('wiki_locks', $params); | |
975 | } | |
976 | } else { | |
977 | $DB->set_field('wiki_locks', 'lockedat', time(), $params); | |
978 | } | |
979 | } | |
980 | ||
981 | /** | |
982 | * Deletes wiki_locks that expired 1 hour ago. | |
983 | */ | |
984 | function wiki_delete_old_locks() { | |
985 | global $DB; | |
986 | ||
987 | $DB->delete_records_select('wiki_locks', "lockedat < ?", array(time() - 3600)); | |
988 | } | |
989 | ||
990 | /** | |
991 | * File processing | |
992 | */ | |
993 | ||
994 | /** | |
995 | * Uploads files to permanent disk space. | |
996 | * | |
44d8a940 PS |
997 | * @param int draftitemid Draft space ID |
998 | * @param int contextid | |
00710f4c DC |
999 | * |
1000 | * @return array of files that have not been inserted. | |
1001 | */ | |
1002 | ||
1003 | function wiki_process_attachments($draftitemid, $deleteuploads, $contextid, $filearea, $itemid, $options = null) { | |
1004 | global $CFG, $USER; | |
1005 | ||
1006 | if (empty($options)) { | |
1007 | $options = page_wiki_edit::$attachmentoptions; | |
1008 | } | |
1009 | ||
1010 | $errors = array(); | |
1011 | ||
1012 | $usercontext = get_context_instance(CONTEXT_USER, $USER->id); | |
1013 | $fs = get_file_storage(); | |
1014 | ||
64f93798 | 1015 | $oldfiles = $fs->get_area_files($contextid, 'mod_wiki', 'attachments', $itemid, 'id'); |
00710f4c DC |
1016 | |
1017 | foreach ($oldfiles as $file) { | |
1018 | if (in_array($file->get_pathnamehash(), $deleteuploads)) { | |
1019 | $file->delete(); | |
1020 | } | |
1021 | } | |
1022 | ||
64f93798 PS |
1023 | $draftfiles = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid, 'id'); |
1024 | $oldfiles = $fs->get_area_files($contextid, 'mod_wiki', 'attachments', $itemid, 'id'); | |
00710f4c | 1025 | |
9730c555 | 1026 | $file_record = array('contextid' => $contextid, 'component' => 'mod_wiki', 'filearea' => 'attachments', 'itemid' => $itemid); |
00710f4c DC |
1027 | //more or less a merge... |
1028 | $newhashes = array(); | |
1029 | foreach ($draftfiles as $file) { | |
64f93798 | 1030 | $newhash = sha1("/$contextid/mod_wiki/attachments/$itemid" . $file->get_filepath() . $file->get_filename()); |
00710f4c DC |
1031 | $newhashes[$newhash] = $file; |
1032 | } | |
1033 | ||
1034 | $filecount = 0; | |
1035 | foreach ($oldfiles as $file) { | |
1036 | $oldhash = $file->get_pathnamehash(); | |
1037 | if (!$file->is_directory() && isset($newhashes[$oldhash])) { | |
1038 | //repeated file: ERROR!!! | |
1039 | unset($newhashes[$oldhash]); | |
1040 | $errors[] = $file; | |
1041 | } | |
1042 | ||
1043 | if (!$file->is_directory()) { | |
1044 | $filecount++; | |
1045 | } | |
1046 | } | |
1047 | ||
1048 | foreach ($newhashes as $file) { | |
1049 | if ($file->get_filepath() !== '/' or $file->is_directory()) { | |
1050 | continue; | |
1051 | } | |
1052 | ||
1053 | if ($options['maxfiles'] and $options['maxfiles'] <= $filecount) { | |
1054 | break; | |
1055 | } | |
1056 | ||
1057 | if (!$file->is_directory()) { | |
1058 | $filecount++; | |
1059 | $fs->create_file_from_storedfile($file_record, $file); | |
1060 | } | |
1061 | } | |
1062 | ||
1063 | //delete all draft files | |
64f93798 | 1064 | $fs->delete_area_files($usercontext->id, 'user', 'draft', $draftitemid); |
00710f4c DC |
1065 | |
1066 | return $errors; | |
1067 | } | |
1068 | ||
9bf1b716 JP |
1069 | function wiki_get_comment($commentid){ |
1070 | global $DB; | |
becf81c7 | 1071 | return $DB->get_record('comments', array('id' => $commentid)); |
9bf1b716 JP |
1072 | } |
1073 | ||
00710f4c DC |
1074 | /** |
1075 | * Returns all comments by context and pageid | |
1076 | * | |
1077 | * @param $context. Current context | |
1078 | * @param $pageid. Current pageid | |
1079 | **/ | |
9ffd2726 | 1080 | function wiki_get_comments($contextid, $pageid) { |
00710f4c DC |
1081 | global $DB; |
1082 | ||
9ffd2726 | 1083 | return $DB->get_records('comments', array('contextid' => $contextid, 'itemid' => $pageid, 'commentarea' => 'wiki_page')); |
00710f4c DC |
1084 | } |
1085 | ||
1086 | /** | |
1087 | * Add comments ro database | |
1088 | * | |
1089 | * @param object $context. Current context | |
1090 | * @param int $pageid. Current pageid | |
1091 | * @param string $content. Content of the comment | |
1092 | * @param string editor. Version of editor we are using. | |
1093 | **/ | |
1094 | function wiki_add_comment($context, $pageid, $content, $editor) { | |
1095 | global $CFG; | |
1096 | require_once($CFG->dirroot . '/comment/lib.php'); | |
1097 | ||
1098 | list($context, $course, $cm) = get_context_info_array($context->id); | |
1099 | $cmt = new stdclass(); | |
1100 | $cmt->context = $context; | |
1101 | $cmt->itemid = $pageid; | |
ab422920 | 1102 | $cmt->area = 'wiki_page'; |
00710f4c | 1103 | $cmt->course = $course; |
d846488e | 1104 | $cmt->component = 'mod_wiki'; |
00710f4c DC |
1105 | |
1106 | $manager = new comment($cmt); | |
1107 | ||
1108 | if ($editor == 'creole') { | |
1109 | $manager->add($content, FORMAT_CREOLE); | |
1110 | } else if ($editor == 'html') { | |
1111 | $manager->add($content, FORMAT_HTML); | |
1112 | } else if ($editor == 'nwiki') { | |
1113 | $manager->add($content, FORMAT_NWIKI); | |
1114 | } | |
1115 | ||
1116 | } | |
1117 | ||
1118 | /** | |
1119 | * Delete comments from database | |
1120 | * | |
1121 | * @param $idcomment. Id of comment which will be deleted | |
1122 | * @param $context. Current context | |
1123 | * @param $pageid. Current pageid | |
1124 | **/ | |
1125 | function wiki_delete_comment($idcomment, $context, $pageid) { | |
1126 | global $CFG; | |
1127 | require_once($CFG->dirroot . '/comment/lib.php'); | |
1128 | ||
1129 | list($context, $course, $cm) = get_context_info_array($context->id); | |
6bdfef5d | 1130 | $cmt = new stdClass(); |
00710f4c DC |
1131 | $cmt->context = $context; |
1132 | $cmt->itemid = $pageid; | |
ab422920 | 1133 | $cmt->area = 'wiki_page'; |
00710f4c | 1134 | $cmt->course = $course; |
d846488e | 1135 | $cmt->component = 'mod_wiki'; |
00710f4c DC |
1136 | |
1137 | $manager = new comment($cmt); | |
1138 | $manager->delete($idcomment); | |
1139 | ||
1140 | } | |
1141 | ||
1142 | /** | |
1143 | * Delete al comments from wiki | |
1144 | * | |
1145 | **/ | |
1146 | function wiki_delete_comments_wiki() { | |
1147 | global $PAGE, $DB; | |
1148 | ||
1149 | $cm = $PAGE->cm; | |
1150 | $context = get_context_instance(CONTEXT_MODULE, $cm->id); | |
1151 | ||
1152 | $table = 'comments'; | |
1153 | $select = 'contextid = ?'; | |
1154 | ||
1155 | $DB->delete_records_select($table, $select, array($context->id)); | |
1156 | ||
1157 | } | |
1158 | ||
1159 | function wiki_add_progress($pageid, $oldversionid, $versionid, $progress) { | |
1160 | global $DB; | |
1161 | for ($v = $oldversionid + 1; $v <= $versionid; $v++) { | |
1162 | $user = wiki_get_wiki_page_id($pageid, $v); | |
1163 | ||
1164 | $DB->insert_record('wiki_progress', array('userid' => $user->userid, 'pageid' => $pageid, 'versionid' => $v, 'progress' => $progress)); | |
1165 | } | |
1166 | } | |
1167 | ||
1168 | function wiki_get_wiki_page_id($pageid, $id) { | |
1169 | global $DB; | |
1170 | return $DB->get_record('wiki_versions', array('pageid' => $pageid, 'id' => $id)); | |
1171 | } | |
1172 | ||
1173 | function wiki_print_page_content($page, $context, $subwikiid) { | |
1174 | global $OUTPUT, $CFG; | |
1175 | ||
1176 | if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) { | |
1177 | $content = wiki_refresh_cachedcontent($page); | |
1178 | $page = $content['page']; | |
1179 | } | |
1180 | ||
1181 | if (isset($content)) { | |
1182 | $box = ''; | |
1183 | foreach ($content['sections'] as $s) { | |
1184 | $box .= '<p>' . get_string('repeatedsection', 'wiki', $s) . '</p>'; | |
1185 | } | |
1186 | ||
1187 | if (!empty($box)) { | |
1188 | echo $OUTPUT->box($box); | |
1189 | } | |
1190 | } | |
64f93798 | 1191 | $html = file_rewrite_pluginfile_urls($page->cachedcontent, 'pluginfile.php', $context->id, 'mod_wiki', 'attachments', $subwikiid); |
367a75fa | 1192 | $html = format_text($html, FORMAT_MOODLE, array('overflowdiv'=>true)); |
00710f4c DC |
1193 | echo $OUTPUT->box($html); |
1194 | ||
1195 | if (!empty($CFG->usetags)) { | |
f0f77dfa | 1196 | $tags = tag_get_tags_array('wiki_pages', $page->id); |
7b8b3662 | 1197 | echo $OUTPUT->container_start('wiki-tags'); |
cc26cb3b | 1198 | echo '<span class="wiki-tags-title">'.get_string('tags').': </span>'; |
7b8b3662 DC |
1199 | $links = array(); |
1200 | foreach ($tags as $tagid=>$tag) { | |
1201 | $url = new moodle_url('/tag/index.php', array('tag'=>$tag)); | |
cc26cb3b | 1202 | $links[] = html_writer::link($url, $tag, array('title'=>get_string('tagtitle', 'wiki', $tag))); |
7b8b3662 DC |
1203 | } |
1204 | echo join($links, ", "); | |
1205 | echo $OUTPUT->container_end(); | |
00710f4c DC |
1206 | } |
1207 | ||
1208 | wiki_increment_pageviews($page); | |
1209 | } | |
1210 | ||
1211 | /** | |
1212 | * This function trims any given text and returns it with some dots at the end | |
1213 | * | |
1214 | * @param string $text | |
1215 | * @param string $limit | |
1216 | * | |
1217 | * @return string | |
1218 | */ | |
1219 | function wiki_trim_string($text, $limit = 25) { | |
1220 | ||
1221 | if (strlen($text) > $limit) { | |
1222 | $text = substr($text, 0, $limit) . '...'; | |
1223 | } | |
1224 | ||
1225 | return $text; | |
1226 | } | |
1227 | ||
1228 | /** | |
1229 | * Prints default edit form fields and buttons | |
1230 | * | |
1231 | * @param string $format Edit form format (html, creole...) | |
1232 | * @param integer $version Version number. A negative number means no versioning. | |
1233 | */ | |
1234 | ||
1235 | function wiki_print_edit_form_default_fields($format, $pageid, $version = -1, $upload = false, $deleteuploads = array()) { | |
1236 | global $CFG, $PAGE, $OUTPUT; | |
1237 | ||
1238 | echo '<input type="hidden" name="sesskey" value="' . sesskey() . '" />'; | |
1239 | ||
1240 | if ($version >= 0) { | |
1241 | echo '<input type="hidden" name="version" value="' . $version . '" />'; | |
1242 | } | |
1243 | ||
1244 | echo '<input type="hidden" name="format" value="' . $format . '"/>'; | |
1245 | ||
1246 | //attachments | |
1247 | require_once($CFG->dirroot . '/lib/form/filemanager.php'); | |
1248 | ||
1249 | $filemanager = new MoodleQuickForm_filemanager('attachments', get_string('wikiattachments', 'wiki'), array('id' => 'attachments'), array('subdirs' => false, 'maxfiles' => 99, 'maxbytes' => $CFG->maxbytes)); | |
1250 | ||
1251 | $value = file_get_submitted_draft_itemid('attachments'); | |
1252 | if (!empty($value) && !$upload) { | |
1253 | $filemanager->setValue($value); | |
1254 | } | |
1255 | ||
1256 | echo "<fieldset class=\"wiki-upload-section clearfix\"><legend class=\"ftoggler\">" . get_string("uploadtitle", 'wiki') . "</legend>"; | |
1257 | ||
1258 | echo $OUTPUT->container_start('mdl-align wiki-form-center aaaaa'); | |
1259 | print $filemanager->toHtml(); | |
1260 | echo $OUTPUT->container_end(); | |
1261 | ||
1262 | $cm = $PAGE->cm; | |
1263 | $context = get_context_instance(CONTEXT_MODULE, $cm->id); | |
1264 | ||
1265 | echo $OUTPUT->container_start('mdl-align wiki-form-center wiki-upload-table'); | |
1266 | wiki_print_upload_table($context, 'wiki_upload', $pageid, $deleteuploads); | |
1267 | echo $OUTPUT->container_end(); | |
1268 | ||
1269 | echo "</fieldset>"; | |
1270 | ||
1271 | echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('save', 'wiki') . '"/>'; | |
1272 | echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('upload', 'wiki') . '"/>'; | |
1273 | echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('preview') . '"/>'; | |
1274 | echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('cancel') . '" />'; | |
1275 | } | |
1276 | ||
1277 | /** | |
1278 | * Prints a table with the files attached to a wiki page | |
1279 | * @param object $context | |
1280 | * @param string $filearea | |
1281 | * @param int $fileitemid | |
1282 | * @param array deleteuploads | |
1283 | */ | |
1284 | function wiki_print_upload_table($context, $filearea, $fileitemid, $deleteuploads = array()) { | |
1285 | global $CFG, $OUTPUT; | |
1286 | ||
1287 | $htmltable = new html_table(); | |
1288 | ||
1289 | $htmltable->head = array(get_string('deleteupload', 'wiki'), get_string('uploadname', 'wiki'), get_string('uploadactions', 'wiki')); | |
1290 | ||
1291 | $fs = get_file_storage(); | |
64f93798 | 1292 | $files = $fs->get_area_files($context->id, 'mod_wiki', $filearea, $fileitemid); //TODO: this is weird (skodak) |
00710f4c DC |
1293 | |
1294 | foreach ($files as $file) { | |
1295 | if (!$file->is_directory()) { | |
1296 | $checkbox = '<input type="checkbox" name="deleteupload[]", value="' . $file->get_pathnamehash() . '"'; | |
1297 | ||
1298 | if (in_array($file->get_pathnamehash(), $deleteuploads)) { | |
1299 | $checkbox .= ' checked="checked"'; | |
1300 | } | |
1301 | ||
1302 | $checkbox .= " />"; | |
1303 | ||
1304 | $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>', ""); | |
1305 | } | |
1306 | } | |
1307 | ||
1308 | print '<h3 class="upload-table-title">' . get_string('uploadfiletitle', 'wiki') . "</h3>"; | |
1309 | print html_writer::table($htmltable); | |
1310 | } | |
1311 | ||
1312 | /** | |
1313 | * Generate wiki's page tree | |
1314 | * | |
1315 | * @param $page. A wiki page object | |
1316 | * @param $node. Starting navigation_node | |
1317 | * @param $keys. An array to store keys | |
1318 | * @return an array with all tree nodes | |
1319 | */ | |
1320 | function wiki_build_tree($page, $node, &$keys) { | |
1321 | $content = array(); | |
1322 | static $icon; | |
1323 | $icon = new pix_icon('f/odt', ''); | |
1324 | $pages = wiki_get_linked_pages($page->id); | |
1325 | foreach ($pages as $p) { | |
1326 | $key = $page->id . ':' . $p->id; | |
1327 | if (in_array($key, $keys)) { | |
1328 | break; | |
1329 | } | |
1330 | array_push($keys, $key); | |
1331 | $l = wiki_parser_link($p); | |
1332 | $link = new moodle_url('/mod/wiki/view.php', array('pageid' => $p->id)); | |
1333 | $nodeaux = $node->add($p->title, $link, null, null, null, $icon); | |
1334 | if ($l['new']) { | |
1335 | $nodeaux->add_class('wiki_newentry'); | |
1336 | } | |
1337 | wiki_build_tree($p, $nodeaux, $keys); | |
1338 | } | |
1339 | $content[] = $node; | |
1340 | return $content; | |
1341 | } | |
1342 | ||
1343 | /** | |
1344 | * Get linked pages from page | |
1345 | * @param int $pageid | |
1346 | */ | |
1347 | function wiki_get_linked_pages($pageid) { | |
1348 | global $DB; | |
1349 | ||
9730c555 | 1350 | $sql = "SELECT p.id, p.title |
e22465c7 PS |
1351 | FROM {wiki_pages} p |
1352 | JOIN {wiki_links} l ON l.topageid = p.id | |
9730c555 JP |
1353 | WHERE l.frompageid = ? |
1354 | ORDER BY p.title ASC"; | |
37dcd4b6 JP |
1355 | return $DB->get_records_sql($sql, array($pageid)); |
1356 | } | |
1357 | ||
1358 | /** | |
1359 | * Get updated pages from wiki | |
1360 | * @param int $pageid | |
1361 | */ | |
1362 | function wiki_get_updated_pages_by_subwiki($swid) { | |
1363 | global $DB, $USER; | |
1364 | ||
9730c555 JP |
1365 | $sql = "SELECT * |
1366 | FROM {wiki_pages} | |
1367 | WHERE subwikiid = ? AND timemodified > ? | |
1368 | ORDER BY timemodified DESC"; | |
37dcd4b6 | 1369 | return $DB->get_records_sql($sql, array($swid, $USER->lastlogin)); |
00710f4c | 1370 | } |