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) {
502 // @TODO: Fix this query
503 return $DB->get_records_select('wiki_pages', "subwikiid=$swid AND title LIKE '%$search%'");
504 //return $DB->get_records_select('wiki_pages', "subwikiid = ? AND title LIKE '%?%'", array($swid, $search));
508 * Search wiki content
509 * @param int $swid sub wiki id
510 * @param string $search
512 function wiki_search_content($swid, $search) {
514 // @TODO: Fix this query
515 return $DB->get_records_select('wiki_pages', "subwikiid=$swid AND cachedcontent LIKE '%$search%'");
516 //return $DB->get_records_select('wiki_pages', "subwikiid = ? AND cachedcontent LIKE '%?%'", array($swid, $search));
520 * Search wiki title and content
521 * @param int $swid sub wiki id
522 * @param string $search
524 function wiki_search_all($swid, $search) {
526 // @TODO: Fix this query
527 return $DB->get_records_select('wiki_pages', "subwikiid=$swid AND (cachedcontent LIKE '%$search%' OR title LIKE '%$search%')");
528 //return $DB->get_records_select('wiki_pages', "subwikiid = ? AND (cachedcontent LIKE '%?%' OR title LIKE '%?%')", array($swid, $search, $search));
532 * Get complete set of user data
534 function wiki_get_user_info($userid) {
535 return get_complete_user_data('id', $userid);
539 * Increase page view nubmer
540 * @param int $page, database record
542 function wiki_increment_pageviews($page) {
546 $DB->update_record('wiki_pages', $page);
549 //----------------------------------------------------------
550 //----------------------------------------------------------
553 * Text format supported by wiki module
555 function wiki_get_formats() {
556 return array('html', 'creole', 'nwiki');
560 * Parses a string with the wiki markup language in $markup.
562 * @return Array or false when something wrong has happened.
564 * Returned array contains the following fields:
565 * 'parsed_text' => String. Contains the parsed wiki content.
566 * 'unparsed_text' => String. Constains the original wiki content.
567 * 'link_count' => Array of array('destination' => ..., 'new' => "is new?"). Contains the internal wiki links found in the wiki content.
568 * 'deleted_sections' => the list of deleted sections.
571 * @author Josep Arús Pous
573 function wiki_parse_content($markup, $pagecontent, $options = array()) {
576 $subwiki = wiki_get_subwiki($options['swid']);
577 $cm = get_coursemodule_from_instance("wiki", $subwiki->wikiid);
578 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
580 $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']));
582 return wiki_parser_proxy::parse($pagecontent, $markup, $parser_options);
586 * This function is the parser callback to parse wiki links.
588 * It returns the necesary information to print a link.
590 * NOTE: Empty pages and non-existent pages must be print in red color.
592 * @param link name of a page
597 * @TODO Doc return and options
599 function wiki_parser_link($link, $options = null) {
602 if (is_object($link)) {
603 $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));
605 $version = wiki_get_current_version($link->id);
606 if ($version->version == 0) {
607 $parsedlink['new'] = true;
611 $swid = $options['swid'];
613 if ($page = wiki_get_page_by_title($swid, $link)) {
614 $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));
616 $version = wiki_get_current_version($page->id);
617 if ($version->version == 0) {
618 $parsedlink['new'] = true;
624 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));
630 * Returns the table fully parsed (HTML)
632 * @return HTML for the table $table
633 * @author Josep Arús Pous
636 function wiki_parser_table($table) {
639 $htmltable = new html_table();
641 $headers = $table[0];
642 $htmltable->head = array();
643 foreach ($headers as $h) {
644 $htmltable->head[] = $h[1];
648 $htmltable->data = array();
649 foreach ($table as $row) {
651 foreach ($row as $r) {
654 $htmltable->data[] = $row_data;
657 return html_writer::table($htmltable);
661 * Returns an absolute path link, unless there is no such link.
663 * @param url Link's URL
664 * @param context filearea params
668 * @return File full path
671 function wiki_parser_real_path($url, $context, $filearea, $fileareaid) {
674 if (preg_match("/^(?:http|ftp)s?\:\/\//", $url)) {
677 return "{$CFG->wwwroot}/pluginfile.php/{$context->id}/$filearea/$fileareaid/$url";
682 * Returns the token used by a wiki language to represent a given tag or "object" (bold -> **)
684 * @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.
685 * @author Josep Arús Pous
687 function wiki_parser_get_token($markup, $name) {
689 return wiki_parser_proxy::get_token($name, $markup);
693 * Checks if current user can view a subwiki
697 function wiki_user_can_view($subwiki) {
700 $wiki = wiki_get_wiki($subwiki->wikiid);
701 $cm = get_coursemodule_from_instance('wiki', $wiki->id);
702 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
704 // Working depending on activity groupmode
705 switch (groups_get_activity_groupmode($cm)) {
708 if ($wiki->wikimode == 'collaborative') {
709 // Collaborative Mode:
710 // There is one wiki for all the class.
712 // Only view capbility needed
713 return has_capability('mod/wiki:viewpage', $context, $USER);
714 } else if ($wiki->wikimode == 'individual') {
716 // Each person owns a wiki.
717 if ($subwiki->userid == $USER->id) {
718 // Only the owner of the wiki can view it
719 return has_capability('mod/wiki:viewpage', $context, $USER);
720 } else { // User has special capabilities
722 // mod/wiki:viewpage capability
724 // mod/wiki:managewiki capability
725 $view = has_capability('mod/wiki:viewpage', $context, $USER);
726 $manage = has_capability('mod/wiki:managewiki', $context, $USER);
728 return $view && $manage;
735 // Collaborative and Individual Mode
737 // Collaborative Mode:
738 // There is one wiki per group.
740 // Each person owns a wiki.
741 if ($wiki->wikimode == 'collaborative' || $wiki->wikimode == 'individual') {
742 // Only members of subwiki group could view that wiki
743 if ($subwiki->groupid == groups_get_activity_group($cm)) {
744 // Only view capability needed
745 return has_capability('mod/wiki:viewpage', $context, $USER);
747 } else { // User is not part of that group
749 // mod/wiki:managewiki capability
751 // moodle/site:accessallgroups capability
753 // mod/wiki:viewpage capability
754 $view = has_capability('mod/wiki:viewpage', $context, $USER);
755 $manage = has_capability('mod/wiki:managewiki', $context, $USER);
756 $access = has_capability('moodle/site:accessallgroups', $context, $USER);
757 return ($manage || $access) && $view;
764 // Collaborative and Individual Mode
766 // Collaborative Mode:
767 // There is one wiki per group.
769 // Each person owns a wiki.
770 if ($wiki->wikimode == 'collaborative' || $wiki->wikimode == 'individual') {
771 // Everybody can read all wikis
773 // Only view capability needed
774 return has_capability('mod/wiki:viewpage', $context, $USER);
785 * Checks if current user can edit a subwiki
789 function wiki_user_can_edit($subwiki) {
792 $wiki = wiki_get_wiki($subwiki->wikiid);
793 $cm = get_coursemodule_from_instance('wiki', $wiki->id);
794 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
796 // Working depending on activity groupmode
797 switch (groups_get_activity_groupmode($cm)) {
800 if ($wiki->wikimode == 'collaborative') {
801 // Collaborative Mode:
802 // There is a wiki for all the class.
804 // Only edit capbility needed
805 return has_capability('mod/wiki:editpage', $context, $USER);
806 } else if ($wiki->wikimode == 'individual') {
808 // There is a wiki per user
810 // Only the owner of that wiki can edit it
811 if ($subwiki->userid == $USER->id) {
812 return has_capability('mod/wiki:editpage', $context, $USER);
813 } else { // Current user is not the owner of that wiki.
816 // mod/wiki:editpage capability
818 // mod/wiki:managewiki capability
819 $edit = has_capability('mod/wiki:editpage', $context, $USER);
820 $manage = has_capability('mod/wiki:managewiki', $context, $USER);
822 return $edit && $manage;
829 if ($wiki->wikimode == 'collaborative') {
830 // Collaborative Mode:
831 // There is one wiki per group.
833 // Only members of subwiki group could edit that wiki
834 if ($subwiki->groupid == groups_get_activity_group($cm)) {
835 // Only edit capability needed
836 return has_capability('mod/wiki:editpage', $context, $USER);
837 } else { // User is not part of that group
839 // mod/wiki:managewiki capability
841 // moodle/site:accessallgroups capability
843 // mod/wiki:editpage capability
844 $manage = has_capability('mod/wiki:managewiki', $context, $USER);
845 $access = has_capability('moodle/site:accessallgroups', $context, $USER);
846 $edit = has_capability('mod/wiki:editpage', $context, $USER);
847 return $manage && $access && $edit;
849 } else if ($wiki->wikimode == 'individual') {
851 // Each person owns a wiki.
853 // Only the owner of that wiki can edit it
854 if ($subwiki->userid == $USER->id) {
855 return has_capability('mod/wiki:editpage', $context, $USER);
856 } else { // Current user is not the owner of that wiki.
858 // mod/wiki:managewiki capability
860 // moodle/site:accessallgroups capability
862 // mod/wiki:editpage capability
863 $manage = has_capability('mod/wiki:managewiki', $context, $USER);
864 $access = has_capability('moodle/site:accessallgroups', $context, $USER);
865 $edit = has_capability('mod/wiki:editpage', $context, $USER);
866 return $manage && $access && $edit;
873 if ($wiki->wikimode == 'collaborative') {
874 // Collaborative Mode:
875 // There is one wiki per group.
877 // Only members of subwiki group could edit that wiki
878 if ($subwiki->groupid == groups_get_activity_group($cm)) {
879 // Only edit capability needed
880 return has_capability('mod/wiki:editpage', $context, $USER);
881 } else { // User is not part of that group
883 // mod/wiki:managewiki capability
885 // mod/wiki:editpage capability
886 $manage = has_capability('mod/wiki:managewiki', $context, $USER);
887 $edit = has_capability('mod/wiki:editpage', $context, $USER);
888 return $manage && $edit;
890 } else if ($wiki->wikimode == 'individual') {
892 // Each person owns a wiki.
894 // Only the owner of that wiki can edit it
895 if ($subwiki->userid == $USER->id) {
896 return has_capability('mod/wiki:editpage', $context, $USER);
897 } else { // Current user is not the owner of that wiki.
899 // mod/wiki:managewiki capability
901 // mod/wiki:editpage capability
902 $manage = has_capability('mod/wiki:managewiki', $context, $USER);
903 $edit = has_capability('mod/wiki:editpage', $context, $USER);
904 return $manage && $edit;
920 * Checks if a page-section is locked.
922 * @return true if the combination of section and page is locked, FALSE otherwise.
924 function wiki_is_page_section_locked($pageid, $userid, $section = null) {
927 $sql = "pageid = ? AND lockedat > ? AND userid != ?";
928 $params = array($pageid, time(), $userid);
930 if (!empty($section)) {
931 $sql .= " AND (sectionname = ? OR sectionname IS null)";
932 $params[] = $section;
935 return $DB->record_exists_select('wiki_locks', $sql, $params);
939 * Inserts or updates a wiki_locks record.
941 function wiki_set_lock($pageid, $userid, $section = null, $insert = false) {
944 if (wiki_is_page_section_locked($pageid, $userid, $section)) {
948 $params = array('pageid' => $pageid, 'userid' => $userid, 'sectionname' => $section);
950 $lock = $DB->get_record('wiki_locks', $params);
953 $DB->update_record('wiki_locks', array('id' => $lock->id, 'lockedat' => time() + LOCK_TIMEOUT));
954 } else if ($insert) {
955 $DB->insert_record('wiki_locks', array('pageid' => $pageid, 'sectionname' => $section, 'userid' => $userid, 'lockedat' => time() + 30));
962 * 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.
964 function wiki_delete_locks($pageid, $userid = null, $section = null, $delete_from_db = true, $delete_section_and_page = false) {
967 $params = array('pageid' => $pageid);
969 if (!empty($userid)) {
970 $params['userid'] = $userid;
973 if (!empty($section)) {
974 $params['sectionname'] = $section;
977 if ($delete_from_db) {
978 $DB->delete_records('wiki_locks', $params);
979 if ($delete_section_and_page && !empty($section)) {
980 $params['sectionname'] = null;
981 $DB->delete_records('wiki_locks', $params);
984 $DB->set_field('wiki_locks', 'lockedat', time(), $params);
989 * Deletes wiki_locks that expired 1 hour ago.
991 function wiki_delete_old_locks() {
994 $DB->delete_records_select('wiki_locks', "lockedat < ?", array(time() - 3600));
1002 * Uploads files to permanent disk space.
1004 * @param draftitemid Draft space ID
1007 * @return array of files that have not been inserted.
1010 function wiki_process_attachments($draftitemid, $deleteuploads, $contextid, $filearea, $itemid, $options = null) {
1013 if (empty($options)) {
1014 $options = page_wiki_edit::$attachmentoptions;
1019 $usercontext = get_context_instance(CONTEXT_USER, $USER->id);
1020 $fs = get_file_storage();
1022 $oldfiles = $fs->get_area_files($contextid, 'mod_wiki', 'attachments', $itemid, 'id');
1024 foreach ($oldfiles as $file) {
1025 if (in_array($file->get_pathnamehash(), $deleteuploads)) {
1030 $draftfiles = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid, 'id');
1031 $oldfiles = $fs->get_area_files($contextid, 'mod_wiki', 'attachments', $itemid, 'id');
1033 $file_record = array('contextid' => $contextid, 'component' => 'mod_wiki', 'filearea' => 'attachments', 'itemid' => $itemid);
1034 //more or less a merge...
1035 $newhashes = array();
1036 foreach ($draftfiles as $file) {
1037 $newhash = sha1("/$contextid/mod_wiki/attachments/$itemid" . $file->get_filepath() . $file->get_filename());
1038 $newhashes[$newhash] = $file;
1042 foreach ($oldfiles as $file) {
1043 $oldhash = $file->get_pathnamehash();
1044 if (!$file->is_directory() && isset($newhashes[$oldhash])) {
1045 //repeated file: ERROR!!!
1046 unset($newhashes[$oldhash]);
1050 if (!$file->is_directory()) {
1055 foreach ($newhashes as $file) {
1056 if ($file->get_filepath() !== '/' or $file->is_directory()) {
1060 if ($options['maxfiles'] and $options['maxfiles'] <= $filecount) {
1064 if (!$file->is_directory()) {
1066 $fs->create_file_from_storedfile($file_record, $file);
1070 //delete all draft files
1071 $fs->delete_area_files($usercontext->id, 'user', 'draft', $draftitemid);
1077 * Returns all comments by context and pageid
1079 * @param $context. Current context
1080 * @param $pageid. Current pageid
1082 function wiki_get_comments($context, $pageid) {
1084 require_once($CFG->dirroot . '/comment/lib.php');
1085 list($context, $course, $cm) = get_context_info_array($context->id);
1087 $cmt = new stdclass();
1088 $cmt->context = $context;
1089 $cmt->itemid = $pageid;
1090 $cmt->pluginname = 'wiki';
1091 $cmt->area = 'wiki_comment_section';
1092 $cmt->course = $course;
1093 $manager = new comment($cmt);
1095 return ($manager->get_comments());
1100 * Returns all comments from wiki comments section by user
1102 * @param $userid. User whose we want get the comments
1104 function wiki_get_comments_by_user($userid) {
1107 $area = 'wiki_comment_section';
1110 WHERE c.userid = ? and c.commentarea = ?";
1112 return $DB->get_records_sql($sql, array($userid, $area));
1117 * Add comments ro database
1119 * @param object $context. Current context
1120 * @param int $pageid. Current pageid
1121 * @param string $content. Content of the comment
1122 * @param string editor. Version of editor we are using.
1124 function wiki_add_comment($context, $pageid, $content, $editor) {
1126 require_once($CFG->dirroot . '/comment/lib.php');
1128 list($context, $course, $cm) = get_context_info_array($context->id);
1129 $cmt = new stdclass();
1130 $cmt->context = $context;
1131 $cmt->itemid = $pageid;
1132 $cmt->area = 'wiki_comment_section';
1133 $cmt->course = $course;
1134 $cmt->pluginname = 'wiki';
1136 $manager = new comment($cmt);
1138 if ($editor == 'creole') {
1139 $manager->add($content, FORMAT_CREOLE);
1140 } else if ($editor == 'html') {
1141 $manager->add($content, FORMAT_HTML);
1142 } else if ($editor == 'nwiki') {
1143 $manager->add($content, FORMAT_NWIKI);
1149 * Delete comments from database
1151 * @param $idcomment. Id of comment which will be deleted
1152 * @param $context. Current context
1153 * @param $pageid. Current pageid
1155 function wiki_delete_comment($idcomment, $context, $pageid) {
1157 require_once($CFG->dirroot . '/comment/lib.php');
1159 list($context, $course, $cm) = get_context_info_array($context->id);
1160 $cmt = new stdclass;
1161 $cmt->context = $context;
1162 $cmt->itemid = $pageid;
1163 $cmt->area = 'wiki_comment_section';
1164 $cmt->pluginname = 'wiki';
1165 $cmt->course = $course;
1167 $manager = new comment($cmt);
1168 $manager->delete($idcomment);
1173 * Delete al comments from wiki
1176 function wiki_delete_comments_wiki() {
1180 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
1182 $table = 'comments';
1183 $select = 'contextid = ?';
1185 $DB->delete_records_select($table, $select, array($context->id));
1189 function wiki_add_progress($pageid, $oldversionid, $versionid, $progress) {
1191 for ($v = $oldversionid + 1; $v <= $versionid; $v++) {
1192 $user = wiki_get_wiki_page_id($pageid, $v);
1194 $DB->insert_record('wiki_progress', array('userid' => $user->userid, 'pageid' => $pageid, 'versionid' => $v, 'progress' => $progress));
1198 function wiki_get_wiki_page_id($pageid, $id) {
1200 return $DB->get_record('wiki_versions', array('pageid' => $pageid, 'id' => $id));
1203 function wiki_print_page_content($page, $context, $subwikiid) {
1204 global $OUTPUT, $CFG;
1206 if ($page->timerendered + WIKI_REFRESH_CACHE_TIME < time()) {
1207 $content = wiki_refresh_cachedcontent($page);
1208 $page = $content['page'];
1211 if (isset($content)) {
1213 foreach ($content['sections'] as $s) {
1214 $box .= '<p>' . get_string('repeatedsection', 'wiki', $s) . '</p>';
1218 echo $OUTPUT->box($box);
1221 $html = file_rewrite_pluginfile_urls($page->cachedcontent, 'pluginfile.php', $context->id, 'mod_wiki', 'attachments', $subwikiid);
1222 $html = format_text($html);
1223 echo $OUTPUT->box($html);
1225 if (!empty($CFG->usetags)) {
1226 $tags = tag_get_tags_array('wiki', $page->id);
1227 echo '<p class="wiki-tags"><span>Tags: </span>' . join($tags, ", ") . '</p>';
1230 wiki_increment_pageviews($page);
1234 * This function trims any given text and returns it with some dots at the end
1236 * @param string $text
1237 * @param string $limit
1241 function wiki_trim_string($text, $limit = 25) {
1243 if (strlen($text) > $limit) {
1244 $text = substr($text, 0, $limit) . '...';
1251 * Prints default edit form fields and buttons
1253 * @param string $format Edit form format (html, creole...)
1254 * @param integer $version Version number. A negative number means no versioning.
1257 function wiki_print_edit_form_default_fields($format, $pageid, $version = -1, $upload = false, $deleteuploads = array()) {
1258 global $CFG, $PAGE, $OUTPUT;
1260 echo '<input type="hidden" name="sesskey" value="' . sesskey() . '" />';
1262 if ($version >= 0) {
1263 echo '<input type="hidden" name="version" value="' . $version . '" />';
1266 echo '<input type="hidden" name="format" value="' . $format . '"/>';
1269 require_once($CFG->dirroot . '/lib/form/filemanager.php');
1271 $filemanager = new MoodleQuickForm_filemanager('attachments', get_string('wikiattachments', 'wiki'), array('id' => 'attachments'), array('subdirs' => false, 'maxfiles' => 99, 'maxbytes' => $CFG->maxbytes));
1273 $value = file_get_submitted_draft_itemid('attachments');
1274 if (!empty($value) && !$upload) {
1275 $filemanager->setValue($value);
1278 echo "<fieldset class=\"wiki-upload-section clearfix\"><legend class=\"ftoggler\">" . get_string("uploadtitle", 'wiki') . "</legend>";
1280 echo $OUTPUT->container_start('mdl-align wiki-form-center aaaaa');
1281 print $filemanager->toHtml();
1282 echo $OUTPUT->container_end();
1285 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
1287 echo $OUTPUT->container_start('mdl-align wiki-form-center wiki-upload-table');
1288 wiki_print_upload_table($context, 'wiki_upload', $pageid, $deleteuploads);
1289 echo $OUTPUT->container_end();
1293 echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('save', 'wiki') . '"/>';
1294 echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('upload', 'wiki') . '"/>';
1295 echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('preview') . '"/>';
1296 echo '<input class="wiki_button" type="submit" name="editoption" value="' . get_string('cancel') . '" />';
1300 * Prints a table with the files attached to a wiki page
1301 * @param object $context
1302 * @param string $filearea
1303 * @param int $fileitemid
1304 * @param array deleteuploads
1306 function wiki_print_upload_table($context, $filearea, $fileitemid, $deleteuploads = array()) {
1307 global $CFG, $OUTPUT;
1309 $htmltable = new html_table();
1311 $htmltable->head = array(get_string('deleteupload', 'wiki'), get_string('uploadname', 'wiki'), get_string('uploadactions', 'wiki'));
1313 $fs = get_file_storage();
1314 $files = $fs->get_area_files($context->id, 'mod_wiki', $filearea, $fileitemid); //TODO: this is weird (skodak)
1316 foreach ($files as $file) {
1317 if (!$file->is_directory()) {
1318 $checkbox = '<input type="checkbox" name="deleteupload[]", value="' . $file->get_pathnamehash() . '"';
1320 if (in_array($file->get_pathnamehash(), $deleteuploads)) {
1321 $checkbox .= ' checked="checked"';
1326 $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>', "");
1330 print '<h3 class="upload-table-title">' . get_string('uploadfiletitle', 'wiki') . "</h3>";
1331 print html_writer::table($htmltable);
1335 * Generate wiki's page tree
1337 * @param $page. A wiki page object
1338 * @param $node. Starting navigation_node
1339 * @param $keys. An array to store keys
1340 * @return an array with all tree nodes
1342 function wiki_build_tree($page, $node, &$keys) {
1345 $icon = new pix_icon('f/odt', '');
1346 $pages = wiki_get_linked_pages($page->id);
1347 foreach ($pages as $p) {
1348 $key = $page->id . ':' . $p->id;
1349 if (in_array($key, $keys)) {
1352 array_push($keys, $key);
1353 $l = wiki_parser_link($p);
1354 $link = new moodle_url('/mod/wiki/view.php', array('pageid' => $p->id));
1355 $nodeaux = $node->add($p->title, $link, null, null, null, $icon);
1357 $nodeaux->add_class('wiki_newentry');
1359 wiki_build_tree($p, $nodeaux, $keys);
1366 * Get linked pages from page
1367 * @param int $pageid
1369 function wiki_get_linked_pages($pageid) {
1372 $sql = "SELECT p.id, p.title
1373 FROM mdl_wiki_pages p
1374 JOIN mdl_wiki_links l ON l.topageid = p.id
1375 WHERE l.frompageid = ?
1376 ORDER BY p.title ASC";
1377 return $DB->get_records_sql($sql, array($pageid));
1381 * Get updated pages from wiki
1382 * @param int $pageid
1384 function wiki_get_updated_pages_by_subwiki($swid) {
1389 WHERE subwikiid = ? AND timemodified > ?
1390 ORDER BY timemodified DESC";
1391 return $DB->get_records_sql($sql, array($swid, $USER->lastlogin));