3 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
19 * This contains functions and classes that will be used by scripts in wiki module
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
25 * @author Jordi Piguillem
27 * @author David Jimenez
29 * @author Daniel Serrano
30 * @author Kenneth Riba
32 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
35 require_once($CFG->dirroot . '/mod/wiki/lib.php');
36 require_once($CFG->dirroot . '/mod/wiki/parser/parser.php');
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', '+');
46 define('LOCK_TIMEOUT', 30);
50 * @param int $wikiid the instance id of wiki
52 function wiki_get_wiki($wikiid) {
55 return $DB->get_record('wiki', array('id' => $wikiid));
59 * Get sub wiki instances with same wiki id
62 function wiki_get_subwikis($wikiid) {
64 return $DB->get_records('wiki_subwikis', array('wikiid' => $wikiid));
68 * Get a sub wiki instance by wiki id and group id
73 function wiki_get_subwiki_by_group($wikiid, $groupid, $userid = 0) {
75 return $DB->get_record('wiki_subwikis', array('wikiid' => $wikiid, 'groupid' => $groupid, 'userid' => $userid));
79 * Get a sub wiki instace by instance id
80 * @param int $subwikiid
83 function wiki_get_subwiki($subwikiid) {
85 return $DB->get_record('wiki_subwikis', array('id' => $subwikiid));
90 * Add a new sub wiki instance
93 * @return int $insertid
95 function wiki_add_subwiki($wikiid, $groupid, $userid = 0) {
98 $record = new StdClass();
99 $record->wikiid = $wikiid;
100 $record->groupid = $groupid;
101 $record->userid = $userid;
103 $insertid = $DB->insert_record('wiki_subwikis', $record);
108 * Get a wiki instance by pageid
112 function wiki_get_wiki_from_pageid($pageid) {
116 FROM {wiki} w, {wiki_subwikis} s, {wiki_pages} p
118 p.subwikiid = s.id AND
121 return $DB->get_record_sql($sql, array($pageid));
125 * Get a wiki page by pageid
129 function wiki_get_page($pageid) {
131 return $DB->get_record('wiki_pages', array('id' => $pageid));
135 * Get latest version of wiki page
139 function wiki_get_current_version($pageid) {
142 // @TODO: Fix this query
146 ORDER BY version DESC
148 return $DB->get_record_sql($sql, array($pageid));
153 * Alias of wiki_get_current_version
154 * @TODO, does the exactly same thing as wiki_get_current_version, should be removed
158 function wiki_get_last_version($pageid) {
159 return wiki_get_current_version($pageid);
165 * @param string $section
167 function wiki_get_section_page($page, $section) {
169 $version = wiki_get_current_version($page->id);
170 return wiki_parser_proxy::get_section($version->content, $version->contentformat, $section);
174 * Get a wiki page by page title
175 * @param int $swid, sub wiki id
176 * @param string $title
179 function wiki_get_page_by_title($swid, $title) {
181 return $DB->get_record('wiki_pages', array('subwikiid' => $swid, 'title' => $title));
185 * Get a version record by record id
186 * @param int $versionid, the version id
189 function wiki_get_version($versionid) {
191 return $DB->get_record('wiki_versions', array('id' => $versionid));
195 * Get first page of wiki instace
196 * @param int $subwikiid
197 * @param int $module, wiki instance object
199 function wiki_get_first_page($subwikid, $module = null) {
203 FROM {wiki} w, {wiki_subwikis} s, {wiki_pages} p
206 w.firstpagetitle = p.title AND
208 return $DB->get_record_sql($sql, array($subwikid));
211 function wiki_save_section($wikipage, $sectiontitle, $sectioncontent, $userid) {
213 $wiki = wiki_get_wiki_from_pageid($wikipage->id);
214 $cm = get_coursemodule_from_instance('wiki', $wiki->id);
215 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
217 if (has_capability('mod/wiki:editpage', $context)) {
218 $version = wiki_get_current_version($wikipage->id);
219 $content = wiki_parser_proxy::get_section($version->content, $version->contentformat, $sectiontitle, true);
221 $newcontent = $content[0] . $sectioncontent . $content[2];
223 return wiki_save_page($wikipage, $newcontent, $userid);
231 * @param object $wikipage
232 * @param string $newcontent
235 function wiki_save_page($wikipage, $newcontent, $userid) {
238 $wiki = wiki_get_wiki_from_pageid($wikipage->id);
239 $cm = get_coursemodule_from_instance('wiki', $wiki->id);
240 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
242 if (has_capability('mod/wiki:editpage', $context)) {
243 $version = wiki_get_current_version($wikipage->id);
245 $version->content = $newcontent;
246 $version->userid = $userid;
248 $version->timecreated = time();
249 if (!$versionid = $DB->insert_record('wiki_versions', $version)) {
253 $wikipage->timemodified = $version->timecreated;
254 $wikipage->userid = $userid;
255 $return = wiki_refresh_cachedcontent($wikipage, $newcontent);
263 function wiki_refresh_cachedcontent($page, $newcontent = null) {
266 $version = wiki_get_current_version($page->id);
267 if (!isset($newcontent)) {
268 $newcontent = $version->content;
271 $options = array('swid' => $page->subwikiid, 'pageid' => $page->id);
272 $parseroutput = wiki_parse_content($version->contentformat, $newcontent, $options);
273 $page->cachedcontent = $parseroutput['toc'] . $parseroutput['parsed_text'];
274 $page->timerendered = time();
275 $DB->update_record('wiki_pages', $page);
277 wiki_refresh_page_links($page, $parseroutput['link_count']);
279 return array('page' => $page, 'sections' => $parseroutput['repeated_sections'], 'version' => $version->version);
284 function wiki_restore_page($wikipage, $newcontent, $userid) {
285 $return = wiki_save_page($wikipage, $newcontent, $userid);
286 return $return['page'];
289 function wiki_refresh_page_links($page, $links) {
292 $DB->delete_records('wiki_links', array('frompageid' => $page->id));
293 foreach ($links as $linkname => $linkinfo) {
295 $newlink = new stdClass();
296 $newlink->subwikiid = $page->subwikiid;
297 $newlink->frompageid = $page->id;
299 if ($linkinfo['new']) {
300 $newlink->tomissingpage = $linkname;
302 $newlink->topageid = $linkinfo['pageid'];
305 $DB->insert_record('wiki_links', $newlink);
311 * Create a new wiki page, if the page exists, return existing pageid
313 * @param string $title
314 * @param string $format
317 function wiki_create_page($swid, $title, $format, $userid) {
319 $subwiki = wiki_get_subwiki($swid);
320 $cm = get_coursemodule_from_instance('wiki', $subwiki->wikiid);
321 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
322 require_capability('mod/wiki:editpage', $context);
324 if ($page = wiki_get_page_by_title($swid, $title)) {
328 // Creating a new empty version
329 $version = new stdClass();
330 $version->content = '';
331 $version->contentformat = $format;
332 $version->version = 0;
333 $version->timecreated = time();
334 $version->userid = $userid;
337 if (!$versionid = $DB->insert_record('wiki_versions', $version)) {
341 // Createing a new empty page
342 $page = new stdClass();
343 $page->subwikiid = $swid;
344 $page->title = $title;
345 $page->cachedcontent = '';
346 $page->timecreated = $version->timecreated;
347 $page->timemodified = $version->timecreated;
348 $page->timerendered = $version->timecreated;
349 $page->userid = $userid;
350 $page->pageviews = 0;
353 $pageid = $DB->insert_record('wiki_pages', $page);
355 // Setting the pageid
356 $version->id = $versionid;
357 $version->pageid = $pageid;
358 $DB->update_record('wiki_versions', $version);
360 wiki_make_cache_expire($page->title);
364 function wiki_make_cache_expire($pagename) {
367 $sql = "UPDATE {wiki_pages}
369 WHERE id IN ( SELECT l.frompageid
371 WHERE l.tomissingpage = ?
373 $DB->execute ($sql, array($pagename));
377 * Get a specific version of page
379 * @param int $version
381 function wiki_get_wiki_page_version($pageid, $version) {
383 return $DB->get_record('wiki_versions', array('pageid' => $pageid, 'version' => $version));
389 * @param int $limitfrom
390 * @param int $limitnum
392 function wiki_get_wiki_page_versions($pageid, $limitfrom, $limitnum) {
394 return $DB->get_records('wiki_versions', array('pageid' => $pageid), 'version DESC', '*', $limitfrom, $limitnum);
398 * Count the number of page version
401 function wiki_count_wiki_page_versions($pageid) {
403 return $DB->count_records('wiki_versions', array('pageid' => $pageid));
407 * Get linked from page
410 function wiki_get_linked_to_pages($pageid) {
412 return $DB->get_records('wiki_links', array('frompageid' => $pageid));
416 * Get linked from page
419 function wiki_get_linked_from_pages($pageid) {
421 return $DB->get_records('wiki_links', array('topageid' => $pageid));
425 * Get pages which user have been edited
429 function wiki_get_contributions($swid, $userid) {
433 FROM {wiki_versions} v, {wiki_pages} p
434 WHERE p.subwikiid = ? AND
438 return $DB->get_records_sql($sql, array($swid, $userid));
442 * Get missing or empty pages in wiki
443 * @param int $swid sub wiki id
445 function wiki_get_missing_or_empty_pages($swid) {
448 $sql = "SELECT DISTINCT p.title, p.id, p.subwikiid
449 FROM {wiki} w, {wiki_subwikis} s, {wiki_pages} p
450 WHERE s.wikiid = w.id and
452 w.firstpagetitle != p.title and
455 FROM {wiki_versions} v
456 WHERE v.pageid = p.id)
458 SELECT DISTINCT l.tomissingpage as title, 0 as id, l.subwikiid
460 WHERE l.subwikiid = ? and
463 return $DB->get_records_sql($sql, array($swid, $swid, $swid));
467 * Get pages list in wiki
468 * @param int $swid sub wiki id
470 function wiki_get_page_list($swid) {
472 $records = $DB->get_records('wiki_pages', array('subwikiid' => $swid), 'title ASC');
477 * Return a list of orphaned wikis for one specific subwiki
479 * @param int $swid sub wiki id
481 function wiki_get_orphaned_pages($swid) {
484 $sql = "SELECT p.id, p.title
485 FROM {wiki_pages} p, {wiki} w , {wiki_subwikis} s
486 WHERE p.subwikiid = ?
489 AND p.title != w.firstpagetitle
490 AND p.id NOT IN (SELECT topageid FROM {wiki_links} WHERE subwikiid = ?);";
492 return $DB->get_records_sql($sql, array($swid, $swid, $swid));
497 * @param int $swid sub wiki id
498 * @param string $search
500 function wiki_search_title($swid, $search) {
503 return $DB->get_records_select('wiki_pages', "subwikiid = ? AND title LIKE ?", array($swid, '%'.$search.'%'));
507 * Search wiki content
508 * @param int $swid sub wiki id
509 * @param string $search
511 function wiki_search_content($swid, $search) {
514 return $DB->get_records_select('wiki_pages', "subwikiid = ? AND cachedcontent LIKE ?", array($swid, '%'.$search.'%'));
518 * Search wiki title and content
519 * @param int $swid sub wiki id
520 * @param string $search
522 function wiki_search_all($swid, $search) {
525 return $DB->get_records_select('wiki_pages', "subwikiid = ? AND (cachedcontent LIKE ? OR title LIKE ?)", array($swid, '%'.$search.'%', '%'.$search.'%'));
529 * Get complete set of user data
531 function wiki_get_user_info($userid) {
532 return get_complete_user_data('id', $userid);
536 * Increase page view nubmer
537 * @param int $page, database record
539 function wiki_increment_pageviews($page) {
543 $DB->update_record('wiki_pages', $page);
546 //----------------------------------------------------------
547 //----------------------------------------------------------
550 * Text format supported by wiki module
552 function wiki_get_formats() {
553 return array('html', 'creole', 'nwiki');
557 * Parses a string with the wiki markup language in $markup.
559 * @return Array or false when something wrong has happened.
561 * Returned array contains the following fields:
562 * 'parsed_text' => String. Contains the parsed wiki content.
563 * 'unparsed_text' => String. Constains the original wiki content.
564 * 'link_count' => Array of array('destination' => ..., 'new' => "is new?"). Contains the internal wiki links found in the wiki content.
565 * 'deleted_sections' => the list of deleted sections.
568 * @author Josep Arús Pous
570 function wiki_parse_content($markup, $pagecontent, $options = array()) {
573 $subwiki = wiki_get_subwiki($options['swid']);
574 $cm = get_coursemodule_from_instance("wiki", $subwiki->wikiid);
575 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
577 $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']));
579 return wiki_parser_proxy::parse($pagecontent, $markup, $parser_options);
583 * This function is the parser callback to parse wiki links.
585 * It returns the necesary information to print a link.
587 * NOTE: Empty pages and non-existent pages must be print in red color.
589 * @param link name of a page
594 * @TODO Doc return and options
596 function wiki_parser_link($link, $options = null) {
599 if (is_object($link)) {
600 $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));
602 $version = wiki_get_current_version($link->id);
603 if ($version->version == 0) {
604 $parsedlink['new'] = true;
608 $swid = $options['swid'];
610 if ($page = wiki_get_page_by_title($swid, $link)) {
611 $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));
613 $version = wiki_get_current_version($page->id);
614 if ($version->version == 0) {
615 $parsedlink['new'] = true;
621 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));
627 * Returns the table fully parsed (HTML)
629 * @return HTML for the table $table
630 * @author Josep Arús Pous
633 function wiki_parser_table($table) {
636 $htmltable = new html_table();
638 $headers = $table[0];
639 $htmltable->head = array();
640 foreach ($headers as $h) {
641 $htmltable->head[] = $h[1];
645 $htmltable->data = array();
646 foreach ($table as $row) {
648 foreach ($row as $r) {
651 $htmltable->data[] = $row_data;
654 return html_writer::table($htmltable);
658 * Returns an absolute path link, unless there is no such link.
660 * @param url Link's URL
661 * @param context filearea params
665 * @return File full path
668 function wiki_parser_real_path($url, $context, $filearea, $fileareaid) {
671 if (preg_match("/^(?:http|ftp)s?\:\/\//", $url)) {
674 return "{$CFG->wwwroot}/pluginfile.php/{$context->id}/$filearea/$fileareaid/$url";
679 * Returns the token used by a wiki language to represent a given tag or "object" (bold -> **)
681 * @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.
682 * @author Josep Arús Pous
684 function wiki_parser_get_token($markup, $name) {
686 return wiki_parser_proxy::get_token($name, $markup);
690 * Checks if current user can view a subwiki
694 function wiki_user_can_view($subwiki) {
697 $wiki = wiki_get_wiki($subwiki->wikiid);
698 $cm = get_coursemodule_from_instance('wiki', $wiki->id);
699 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
701 // Working depending on activity groupmode
702 switch (groups_get_activity_groupmode($cm)) {
705 if ($wiki->wikimode == 'collaborative') {
706 // Collaborative Mode:
707 // There is one wiki for all the class.
709 // Only view capbility needed
710 return has_capability('mod/wiki:viewpage', $context, $USER);
711 } else if ($wiki->wikimode == 'individual') {
713 // Each person owns a wiki.
714 if ($subwiki->userid == $USER->id) {
715 // Only the owner of the wiki can view it
716 return has_capability('mod/wiki:viewpage', $context, $USER);
717 } else { // User has special capabilities
719 // mod/wiki:viewpage capability
721 // mod/wiki:managewiki capability
722 $view = has_capability('mod/wiki:viewpage', $context, $USER);
723 $manage = has_capability('mod/wiki:managewiki', $context, $USER);
725 return $view && $manage;
732 // Collaborative and Individual Mode
734 // Collaborative Mode:
735 // There is one wiki per group.
737 // Each person owns a wiki.
738 if ($wiki->wikimode == 'collaborative' || $wiki->wikimode == 'individual') {
739 // Only members of subwiki group could view that wiki
740 if ($subwiki->groupid == groups_get_activity_group($cm)) {
741 // Only view capability needed
742 return has_capability('mod/wiki:viewpage', $context, $USER);
744 } else { // User is not part of that group
746 // mod/wiki:managewiki capability
748 // moodle/site:accessallgroups capability
750 // mod/wiki:viewpage capability
751 $view = has_capability('mod/wiki:viewpage', $context, $USER);
752 $manage = has_capability('mod/wiki:managewiki', $context, $USER);
753 $access = has_capability('moodle/site:accessallgroups', $context, $USER);
754 return ($manage || $access) && $view;
761 // Collaborative and Individual Mode
763 // Collaborative Mode:
764 // There is one wiki per group.
766 // Each person owns a wiki.
767 if ($wiki->wikimode == 'collaborative' || $wiki->wikimode == 'individual') {
768 // Everybody can read all wikis
770 // Only view capability needed
771 return has_capability('mod/wiki:viewpage', $context, $USER);
782 * Checks if current user can edit a subwiki
786 function wiki_user_can_edit($subwiki) {
789 $wiki = wiki_get_wiki($subwiki->wikiid);
790 $cm = get_coursemodule_from_instance('wiki', $wiki->id);
791 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
793 // Working depending on activity groupmode
794 switch (groups_get_activity_groupmode($cm)) {
797 if ($wiki->wikimode == 'collaborative') {
798 // Collaborative Mode:
799 // There is a wiki for all the class.
801 // Only edit capbility needed
802 return has_capability('mod/wiki:editpage', $context, $USER);
803 } else if ($wiki->wikimode == 'individual') {
805 // There is a wiki per user
807 // Only the owner of that wiki can edit it
808 if ($subwiki->userid == $USER->id) {
809 return has_capability('mod/wiki:editpage', $context, $USER);
810 } else { // Current user is not the owner of that wiki.
813 // mod/wiki:editpage capability
815 // mod/wiki:managewiki capability
816 $edit = has_capability('mod/wiki:editpage', $context, $USER);
817 $manage = has_capability('mod/wiki:managewiki', $context, $USER);
819 return $edit && $manage;
826 if ($wiki->wikimode == 'collaborative') {
827 // Collaborative Mode:
828 // There is one wiki per group.
830 // Only members of subwiki group could edit that wiki
831 if ($subwiki->groupid == groups_get_activity_group($cm)) {
832 // Only edit capability needed
833 return has_capability('mod/wiki:editpage', $context, $USER);
834 } else { // User is not part of that group
836 // mod/wiki:managewiki capability
838 // moodle/site:accessallgroups capability
840 // mod/wiki:editpage capability
841 $manage = has_capability('mod/wiki:managewiki', $context, $USER);
842 $access = has_capability('moodle/site:accessallgroups', $context, $USER);
843 $edit = has_capability('mod/wiki:editpage', $context, $USER);
844 return $manage && $access && $edit;
846 } else if ($wiki->wikimode == 'individual') {
848 // Each person owns a wiki.
850 // Only the owner of that wiki can edit it
851 if ($subwiki->userid == $USER->id) {
852 return has_capability('mod/wiki:editpage', $context, $USER);
853 } else { // Current user is not the owner of that wiki.
855 // mod/wiki:managewiki capability
857 // moodle/site:accessallgroups capability
859 // mod/wiki:editpage capability
860 $manage = has_capability('mod/wiki:managewiki', $context, $USER);
861 $access = has_capability('moodle/site:accessallgroups', $context, $USER);
862 $edit = has_capability('mod/wiki:editpage', $context, $USER);
863 return $manage && $access && $edit;
870 if ($wiki->wikimode == 'collaborative') {
871 // Collaborative Mode:
872 // There is one wiki per group.
874 // Only members of subwiki group could edit that wiki
875 if ($subwiki->groupid == groups_get_activity_group($cm)) {
876 // Only edit capability needed
877 return has_capability('mod/wiki:editpage', $context, $USER);
878 } else { // User is not part of that group
880 // mod/wiki:managewiki capability
882 // mod/wiki:editpage capability
883 $manage = has_capability('mod/wiki:managewiki', $context, $USER);
884 $edit = has_capability('mod/wiki:editpage', $context, $USER);
885 return $manage && $edit;
887 } else if ($wiki->wikimode == 'individual') {
889 // Each person owns a wiki.
891 // Only the owner of that wiki can edit it
892 if ($subwiki->userid == $USER->id) {
893 return has_capability('mod/wiki:editpage', $context, $USER);
894 } else { // Current user is not the owner of that wiki.
896 // mod/wiki:managewiki capability
898 // mod/wiki:editpage capability
899 $manage = has_capability('mod/wiki:managewiki', $context, $USER);
900 $edit = has_capability('mod/wiki:editpage', $context, $USER);
901 return $manage && $edit;
917 * Checks if a page-section is locked.
919 * @return true if the combination of section and page is locked, FALSE otherwise.
921 function wiki_is_page_section_locked($pageid, $userid, $section = null) {
924 $sql = "pageid = ? AND lockedat > ? AND userid != ?";
925 $params = array($pageid, time(), $userid);
927 if (!empty($section)) {
928 $sql .= " AND (sectionname = ? OR sectionname IS null)";
929 $params[] = $section;
932 return $DB->record_exists_select('wiki_locks', $sql, $params);
936 * Inserts or updates a wiki_locks record.
938 function wiki_set_lock($pageid, $userid, $section = null, $insert = false) {
941 if (wiki_is_page_section_locked($pageid, $userid, $section)) {
945 $params = array('pageid' => $pageid, 'userid' => $userid, 'sectionname' => $section);
947 $lock = $DB->get_record('wiki_locks', $params);
950 $DB->update_record('wiki_locks', array('id' => $lock->id, 'lockedat' => time() + LOCK_TIMEOUT));
951 } else if ($insert) {
952 $DB->insert_record('wiki_locks', array('pageid' => $pageid, 'sectionname' => $section, 'userid' => $userid, 'lockedat' => time() + 30));
959 * 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.
961 function wiki_delete_locks($pageid, $userid = null, $section = null, $delete_from_db = true, $delete_section_and_page = false) {
964 $params = array('pageid' => $pageid);
966 if (!empty($userid)) {
967 $params['userid'] = $userid;
970 if (!empty($section)) {
971 $params['sectionname'] = $section;
974 if ($delete_from_db) {
975 $DB->delete_records('wiki_locks', $params);
976 if ($delete_section_and_page && !empty($section)) {
977 $params['sectionname'] = null;
978 $DB->delete_records('wiki_locks', $params);
981 $DB->set_field('wiki_locks', 'lockedat', time(), $params);
986 * Deletes wiki_locks that expired 1 hour ago.
988 function wiki_delete_old_locks() {
991 $DB->delete_records_select('wiki_locks', "lockedat < ?", array(time() - 3600));
999 * Uploads files to permanent disk space.
1001 * @param draftitemid Draft space ID
1004 * @return array of files that have not been inserted.
1007 function wiki_process_attachments($draftitemid, $deleteuploads, $contextid, $filearea, $itemid, $options = null) {
1010 if (empty($options)) {
1011 $options = page_wiki_edit::$attachmentoptions;
1016 $usercontext = get_context_instance(CONTEXT_USER, $USER->id);
1017 $fs = get_file_storage();
1019 $oldfiles = $fs->get_area_files($contextid, 'mod_wiki', 'attachments', $itemid, 'id');
1021 foreach ($oldfiles as $file) {
1022 if (in_array($file->get_pathnamehash(), $deleteuploads)) {
1027 $draftfiles = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid, 'id');
1028 $oldfiles = $fs->get_area_files($contextid, 'mod_wiki', 'attachments', $itemid, 'id');
1030 $file_record = array('contextid' => $contextid, 'component' => 'mod_wiki', 'filearea' => 'attachments', 'itemid' => $itemid);
1031 //more or less a merge...
1032 $newhashes = array();
1033 foreach ($draftfiles as $file) {
1034 $newhash = sha1("/$contextid/mod_wiki/attachments/$itemid" . $file->get_filepath() . $file->get_filename());
1035 $newhashes[$newhash] = $file;
1039 foreach ($oldfiles as $file) {
1040 $oldhash = $file->get_pathnamehash();
1041 if (!$file->is_directory() && isset($newhashes[$oldhash])) {
1042 //repeated file: ERROR!!!
1043 unset($newhashes[$oldhash]);
1047 if (!$file->is_directory()) {
1052 foreach ($newhashes as $file) {
1053 if ($file->get_filepath() !== '/' or $file->is_directory()) {
1057 if ($options['maxfiles'] and $options['maxfiles'] <= $filecount) {
1061 if (!$file->is_directory()) {
1063 $fs->create_file_from_storedfile($file_record, $file);
1067 //delete all draft files
1068 $fs->delete_area_files($usercontext->id, 'user', 'draft', $draftitemid);
1074 * Returns all comments by context and pageid
1076 * @param $context. Current context
1077 * @param $pageid. Current pageid
1079 function wiki_get_comments($context, $pageid) {
1081 require_once($CFG->dirroot . '/comment/lib.php');
1082 list($context, $course, $cm) = get_context_info_array($context->id);
1084 $cmt = new stdclass();
1085 $cmt->context = $context;
1086 $cmt->itemid = $pageid;
1087 $cmt->pluginname = 'wiki';
1088 $cmt->area = 'wiki_comment_section';
1089 $cmt->course = $course;
1090 $manager = new comment($cmt);
1092 return ($manager->get_comments());
1097 * Returns all comments from wiki comments section by user
1099 * @param $userid. User whose we want get the comments
1101 function wiki_get_comments_by_user($userid) {
1104 $area = 'wiki_comment_section';
1107 WHERE c.userid = ? and c.commentarea = ?";
1109 return $DB->get_records_sql($sql, array($userid, $area));
1114 * Add comments ro database
1116 * @param object $context. Current context
1117 * @param int $pageid. Current pageid
1118 * @param string $content. Content of the comment
1119 * @param string editor. Version of editor we are using.
1121 function wiki_add_comment($context, $pageid, $content, $editor) {
1123 require_once($CFG->dirroot . '/comment/lib.php');
1125 list($context, $course, $cm) = get_context_info_array($context->id);
1126 $cmt = new stdclass();
1127 $cmt->context = $context;
1128 $cmt->itemid = $pageid;
1129 $cmt->area = 'wiki_comment_section';
1130 $cmt->course = $course;
1131 $cmt->pluginname = 'wiki';
1133 $manager = new comment($cmt);
1135 if ($editor == 'creole') {
1136 $manager->add($content, FORMAT_CREOLE);
1137 } else if ($editor == 'html') {
1138 $manager->add($content, FORMAT_HTML);
1139 } else if ($editor == 'nwiki') {
1140 $manager->add($content, FORMAT_NWIKI);
1146 * Delete comments from database
1148 * @param $idcomment. Id of comment which will be deleted
1149 * @param $context. Current context
1150 * @param $pageid. Current pageid
1152 function wiki_delete_comment($idcomment, $context, $pageid) {
1154 require_once($CFG->dirroot . '/comment/lib.php');
1156 list($context, $course, $cm) = get_context_info_array($context->id);
1157 $cmt = new stdclass;
1158 $cmt->context = $context;
1159 $cmt->itemid = $pageid;
1160 $cmt->area = 'wiki_comment_section';
1161 $cmt->pluginname = 'wiki';
1162 $cmt->course = $course;
1164 $manager = new comment($cmt);
1165 $manager->delete($idcomment);
1170 * Delete al comments from wiki
1173 function wiki_delete_comments_wiki() {
1177 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
1179 $table = 'comments';
1180 $select = 'contextid = ?';
1182 $DB->delete_records_select($table, $select, array($context->id));
1186 function wiki_add_progress($pageid, $oldversionid, $versionid, $progress) {
1188 for ($v = $oldversionid + 1; $v <= $versionid; $v++) {
1189 $user = wiki_get_wiki_page_id($pageid, $v);
1191 $DB->insert_record('wiki_progress', array('userid' => $user->userid, 'pageid' => $pageid, 'versionid' => $v, 'progress' => $progress));
1195 function wiki_get_wiki_page_id($pageid, $id) {
1197 return $DB->get_record('wiki_versions', array('pageid' => $pageid, 'id' => $id));
1200 function wiki_print_page_content($page, $context, $subwikiid) {
1201 global $OUTPUT, $CFG;
1203 if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1204 $content = wiki_refresh_cachedcontent($page);
1205 $page = $content['page'];
1208 if (isset($content)) {
1210 foreach ($content['sections'] as $s) {
1211 $box .= '<p>' . get_string('repeatedsection', 'wiki', $s) . '</p>';
1215 echo $OUTPUT->box($box);
1218 $html = file_rewrite_pluginfile_urls($page->cachedcontent, 'pluginfile.php', $context->id, 'mod_wiki', 'attachments', $subwikiid);
1219 $html = format_text($html);
1220 echo $OUTPUT->box($html);
1222 if (!empty($CFG->usetags)) {
1223 $tags = tag_get_tags_array('wiki', $page->id);
1224 echo '<p class="wiki-tags"><span>Tags: </span>' . join($tags, ", ") . '</p>';
1227 wiki_increment_pageviews($page);
1231 * This function trims any given text and returns it with some dots at the end
1233 * @param string $text
1234 * @param string $limit
1238 function wiki_trim_string($text, $limit = 25) {
1240 if (strlen($text) > $limit) {
1241 $text = substr($text, 0, $limit) . '...';
1248 * Prints default edit form fields and buttons
1250 * @param string $format Edit form format (html, creole...)
1251 * @param integer $version Version number. A negative number means no versioning.
1254 function wiki_print_edit_form_default_fields($format, $pageid, $version = -1, $upload = false, $deleteuploads = array()) {
1255 global $CFG, $PAGE, $OUTPUT;
1257 echo '<input type="hidden" name="sesskey" value="' . sesskey() . '" />';
1259 if ($version >= 0) {
1260 echo '<input type="hidden" name="version" value="' . $version . '" />';
1263 echo '<input type="hidden" name="format" value="' . $format . '"/>';
1266 require_once($CFG->dirroot . '/lib/form/filemanager.php');
1268 $filemanager = new MoodleQuickForm_filemanager('attachments', get_string('wikiattachments', 'wiki'), array('id' => 'attachments'), array('subdirs' => false, 'maxfiles' => 99, 'maxbytes' => $CFG->maxbytes));
1270 $value = file_get_submitted_draft_itemid('attachments');
1271 if (!empty($value) && !$upload) {
1272 $filemanager->setValue($value);
1275 echo "<fieldset class=\"wiki-upload-section clearfix\"><legend class=\"ftoggler\">" . get_string("uploadtitle", 'wiki') . "</legend>";
1277 echo $OUTPUT->container_start('mdl-align wiki-form-center aaaaa');
1278 print $filemanager->toHtml();
1279 echo $OUTPUT->container_end();
1282 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
1284 echo $OUTPUT->container_start('mdl-align wiki-form-center wiki-upload-table');
1285 wiki_print_upload_table($context, 'wiki_upload', $pageid, $deleteuploads);
1286 echo $OUTPUT->container_end();
1290 echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('save', 'wiki') . '"/>';
1291 echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('upload', 'wiki') . '"/>';
1292 echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('preview') . '"/>';
1293 echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('cancel') . '" />';
1297 * Prints a table with the files attached to a wiki page
1298 * @param object $context
1299 * @param string $filearea
1300 * @param int $fileitemid
1301 * @param array deleteuploads
1303 function wiki_print_upload_table($context, $filearea, $fileitemid, $deleteuploads = array()) {
1304 global $CFG, $OUTPUT;
1306 $htmltable = new html_table();
1308 $htmltable->head = array(get_string('deleteupload', 'wiki'), get_string('uploadname', 'wiki'), get_string('uploadactions', 'wiki'));
1310 $fs = get_file_storage();
1311 $files = $fs->get_area_files($context->id, 'mod_wiki', $filearea, $fileitemid); //TODO: this is weird (skodak)
1313 foreach ($files as $file) {
1314 if (!$file->is_directory()) {
1315 $checkbox = '<input type="checkbox" name="deleteupload[]", value="' . $file->get_pathnamehash() . '"';
1317 if (in_array($file->get_pathnamehash(), $deleteuploads)) {
1318 $checkbox .= ' checked="checked"';
1323 $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>', "");
1327 print '<h3 class="upload-table-title">' . get_string('uploadfiletitle', 'wiki') . "</h3>";
1328 print html_writer::table($htmltable);
1332 * Generate wiki's page tree
1334 * @param $page. A wiki page object
1335 * @param $node. Starting navigation_node
1336 * @param $keys. An array to store keys
1337 * @return an array with all tree nodes
1339 function wiki_build_tree($page, $node, &$keys) {
1342 $icon = new pix_icon('f/odt', '');
1343 $pages = wiki_get_linked_pages($page->id);
1344 foreach ($pages as $p) {
1345 $key = $page->id . ':' . $p->id;
1346 if (in_array($key, $keys)) {
1349 array_push($keys, $key);
1350 $l = wiki_parser_link($p);
1351 $link = new moodle_url('/mod/wiki/view.php', array('pageid' => $p->id));
1352 $nodeaux = $node->add($p->title, $link, null, null, null, $icon);
1354 $nodeaux->add_class('wiki_newentry');
1356 wiki_build_tree($p, $nodeaux, $keys);
1363 * Get linked pages from page
1364 * @param int $pageid
1366 function wiki_get_linked_pages($pageid) {
1369 $sql = "SELECT p.id, p.title
1370 FROM mdl_wiki_pages p
1371 JOIN mdl_wiki_links l ON l.topageid = p.id
1372 WHERE l.frompageid = ?
1373 ORDER BY p.title ASC";
1374 return $DB->get_records_sql($sql, array($pageid));
1378 * Get updated pages from wiki
1379 * @param int $pageid
1381 function wiki_get_updated_pages_by_subwiki($swid) {
1386 WHERE subwikiid = ? AND timemodified > ?
1387 ORDER BY timemodified DESC";
1388 return $DB->get_records_sql($sql, array($swid, $USER->lastlogin));