ÿØÿà JFIF    ÿÛ „  ( %!1"%)+...383-7(-.+  -%%--------+------------/----------------------------ÿÀ  ¶" ÿÄ     ÿÄ @    !1AQaq‘¡"±ÁÑð2’BRráS‚ñ3b¢CT²Ò #cÿÄ    ÿÄ '   1!AQ2a"‘±#ÿÚ   ? ò(/p‘—–¢·,M|¯G»R£üešT. ôŸEoCFñ‡ 4ÔkåóxR|µÁ¨ÓDà!Ç´µ˜‡p ÍQ‹§!þž^õWsŒy  åÁ§$á«%ºq˜™JyyË0y«^Ϗ -3ÃÏËÈ£Æ\P’ä„s&•‹Üs üô'àWt¹pñCp$bÚF`·7.^)¾!)ÒÙ˜–ÅÏš^h¾ø³·ìe±ŒaeÖ—Í,e=B}Jéߦ$$½—šÙÜCC¯¶è8β–Åkèwx LÉngT±æ¹£Ócœ¿Í/©Éÿ ‰ÚCÒ­mq;Tt¶–}0"zÖPcd1š­¤tˆ„ÐÓâqú[™öUCŠ2޿د­É(¸ßúçšmW,Ò ºf‹Ån™ÄLêÁ8üÁkÁ€L¥ÍuJ1œôrÂSŒÓöt!7EUíïb)AËi¬â-ÙHk8òÁiXYwÅ)O^"ÇØriÛô{»wRUKÙÏÚlÓ¬€‚’שT ] ªb—ÊîKC^×M“xùäñz¬zJ× {4[¹M'IÆeH1LCWÕ]œûº WDæà°OÅ‚¹c²ÞuA–rL`HšpCez‡V’— Ž‚Ë„–ñ­'µR0ÕÖ=À:±G»C\nÆÉ5*¢ †3šhQ4ýÒi$Õ1"Ü]¢p-q3zcQ$ªö¨¥æf›‘»´ÝÚHá„e²JÇ–iÊ:·à¬Øc5Åk»Laª*wi [0Ówk ¦a¦0Õ²ÅÅ‚T¸’³q:Æ<¹ú Ò˜Æ}2VE•Ѐp¡Ô3Úº …h³^LJºçì¥Ánó|˜ÖˆÎˆ+« ¦dø‘Mº–d\ªDðÛ„Ì×LÝ——Ð9Ç|•FèçVm™¨€™3õS–9Äå¢<̉Ìm¢±`·º˜&Z²ž Ë®D«¶»6™‰©­HÈ Àá«h­i³04æ’hxœi3ï¨(ÓL·†‹¶ËpŒ ƒÜÒ? :õdsÀ –3æÓ·Üjâ¬9—]8n¼&]I F£¼…ì–—Œ0v°LǐÅfÛ2TÖ’aµ˜N@ÖBSÏ^à´4-±°b×nÈÈœÆD=KdŒø…ÄÈK,›ÖR§fjü$^ÔÎ!„6^ s:Üun\ôkCÞò÷<—Lúl Í›G¹ÀPá¼Nc¡šÒ…ÙWͳœ±vÊáЄ×9‹P‰cEØ‘™›µŸP<×g1 º©Ø¬wiÁ^l5× I/';Ë+´Z‡ÓÄFÕp[Èð’ HÄ ó 9¬Dl4“é±Ï”V=^Hð;žLädÉa‚°Ë,#/Ž~²BÔÛ QãñQtIeórVB,ÏÂf‹4#Μc‹É3ZIÖ Œ¢¥·üxa‡Ãçè„jŠ[5 Ä!U?,3žÎ×…ðdÓ÷háŠA‰ìÄ4÷ÃÜZÃE{‰®+W\ZÍE[‰»µk»MÝ­`¢©†˜ÃV‹-f¢¡†¢a«eŠ%«Y¨©q%jâd,Ôq`) ¤¦…šˆ ¦E>0Ùb²t–Ÿ  ÷jsςҒKÈcø(é›;k(’#ôŒQ ™C> õ³M9óºÆµ¤çâ;uÀ)5>RÔ¸fÓ~Ȧ—’-$fe«"FâUˆÊwµPÏu w+"åÉó¨6s™Û9(À¨ù©hE°½†n`m~“@©›p!Vkhµ Á1šbEqqÊ@ºèl›2 –Yã%‘‚hÛ{a¶‡ÅÞM²¬çL34®Çl]®‹ŽØŒm'RÜe35æöˆ­Á­ cP9šeÁköo´L³Ì=p8]”‡B¶,šº|ɏdzXˆØk*ÇÚ{#ñ‰pã(€¶‡9ý'šÜ³½¯kƒ†Â’ëSOƒ•Å®H6+a¢µˆ‹Y¨b˜b+XˆÖ!°u!¢"µˆˆn2ˆ Å0Ä`Å Ô®c(ÓÜGº•Ä»Œ âWî%q.áÐÄ÷î%umÍ£+ÜQ,Vn¦-GphU¸¢X­&,Gt ·K¢ÅÅ·¥RÄÊÉbKn N­R2g$VµÕó Qr#–ÓZUÏð0ÎtÙÀœz ëöo“Îk¯n„T°"SÞ+³/…€½"ižãO%Í%&Δâ‘ËØ´IˆÓ°Ë‰ÞM3.™yçÁzit›`4C`k¢¼á!álÄï sÂ[×!¤l¾æo"ƒIÔ'@ªu)3›ô®“@Z à¾] üœ'‡4¸PÞkÁ-qÄH‰ÓÍBd´ÿ —¹°ÄA&ÊUC„öz‚‚RæŠtf¬>˜ÑidšEçÑL÷áý¡V±h§­c¿¥¨ƒ@g¼…Ýö^ÞËc.ž„æ“I[ ª+·zÐÒÚ,½Ð»¶€C›7jk$๖€Ž¾ÅÙpp¶ÍþéΤ ½ØÎŒq ñpæžÅ¥#Øâ49ÃÂK^MYV“,¶Éz_òæ:…;Õ«¦I3âJ£¤û5$7Èxün\â]Êe¯(Ÿ&Ž‹¶2<6Ćf× æ¢ƱqWı[(ÙÂŽç‚T7¨@ÈÉÍß‚ïÙ"&3TYlGށ†)†#5ŠA©^T2ÆÁ†)©†©†¤yGXÁ†©"†)©¼ÅV WS†#©]R–r‹q5ÕbâWþBh¯u+ªÅÄ×ü„nÑ^êkªÁj‰jeœWˆÕÕ`µDµ2Ì+Ä µDµµ5Ô{¤Þ0RF’H÷AÛ<ÊÁ§ ƈæ0Ñ£ê4 öÚµ[¬/1²€â<-¬šö²r×0o×w ´xÐÒË„ g01¬„åEM蛇Ã\6µE›‘fÙO k÷CºnÓ1`iîÒ² áÂ!ÑLÄÿ ³¬\õ*:M=Ç»c‹2[‰ØsÕLò\ŒK L^™üÄN\¶#» Ç\……ßïIœÉ$¸ÎñÍ®ÔHÇ Ûí/´>Li”„†g^$ 7NÍÑÑ2M2ªNg=k½Ð}Ÿl6‡ —JWˆ”ÞéT·+µ¦üÂFè¢Vs6ýÆ4»2+2IÝ9ô9®ÇGÙÇ1+Ä8;*Õ§ž½D*îÑWÚçá3Ma¤·ˆ¥t}š²Ü…Q+Æüµ8HíS”üxGéÁˆ¦Ël„éÈ 5 µÄƒ6äÜ(kIš¯S†fÖ&¸®×v|Äyˆ*禌Éù@7-®Ä[]ÎÖ¿ê`º…=:…žJVnݳvðÖKE¼‚ »mà ÷f®:Ë ™–4rð¡4` ܹçž~‹C=œ…¾Ïj|VDtK.ƒ"9 Ï ­–éXá³6WÒïIL-Ї Ç filesedit.php000064400000007534152265517660007255 0ustar00. /** * Manage files in wiki * * @package mod_wiki * @copyright 2011 Dongsheng Cai * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require(__DIR__.'/../../config.php'); require_once('lib.php'); require_once('locallib.php'); require_once("$CFG->dirroot/mod/wiki/filesedit_form.php"); require_once("$CFG->dirroot/repository/lib.php"); $subwikiid = required_param('subwiki', PARAM_INT); // not being used for file management, we use it to generate navbar link $pageid = optional_param('pageid', 0, PARAM_INT); $returnurl = optional_param('returnurl', '', PARAM_LOCALURL); if (!$subwiki = wiki_get_subwiki($subwikiid)) { throw new \moodle_exception('incorrectsubwikiid', 'wiki'); } // Checking wiki instance of that subwiki if (!$wiki = wiki_get_wiki($subwiki->wikiid)) { throw new \moodle_exception('incorrectwikiid', 'wiki'); } // Checking course module instance if (!$cm = get_coursemodule_from_instance("wiki", $subwiki->wikiid)) { throw new \moodle_exception('invalidcoursemodule'); } // Checking course instance $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); $context = context_module::instance($cm->id); require_login($course, true, $cm); if (!wiki_user_can_view($subwiki, $wiki)) { throw new \moodle_exception('cannotviewpage', 'wiki'); } require_capability('mod/wiki:managefiles', $context); if (empty($returnurl)) { $referer = get_local_referer(false); if (!empty($referer)) { $returnurl = $referer; } else { $returnurl = new moodle_url('/mod/wiki/files.php', array('subwiki' => $subwiki->id, 'pageid' => $pageid)); } } $title = get_string('editfiles', 'wiki'); $struser = get_string('user'); $url = new moodle_url('/mod/wiki/filesedit.php', array('subwiki'=>$subwiki->id, 'pageid'=>$pageid)); $PAGE->set_url($url); $PAGE->set_context($context); $PAGE->set_title($title); $PAGE->set_heading($course->fullname); $PAGE->navbar->add(format_string(get_string('wikifiles', 'wiki')), $CFG->wwwroot . '/mod/wiki/files.php?pageid=' . $pageid); $PAGE->navbar->add(format_string($title)); $PAGE->set_secondary_active_tab('modulepage'); $PAGE->activityheader->set_attrs([ 'hidecompletion' => true ]); $PAGE->add_body_class('limitedwidth'); $data = new stdClass(); $data->returnurl = $returnurl; $data->subwikiid = $subwiki->id; $maxbytes = get_max_upload_file_size($CFG->maxbytes, $COURSE->maxbytes); $types = FILE_INTERNAL | FILE_REFERENCE | FILE_CONTROLLED_LINK; $options = array('subdirs' => 0, 'maxbytes' => $maxbytes, 'maxfiles' => -1, 'accepted_types' => '*', 'return_types' => $types); file_prepare_standard_filemanager($data, 'files', $options, $context, 'mod_wiki', 'attachments', $subwiki->id); $mform = new mod_wiki_filesedit_form(null, array('data'=>$data, 'options'=>$options)); if ($mform->is_cancelled()) { redirect($returnurl); } else if ($formdata = $mform->get_data()) { $formdata = file_postupdate_standard_filemanager($formdata, 'files', $options, $context, 'mod_wiki', 'attachments', $subwiki->id); redirect($returnurl); } echo $OUTPUT->header(); echo $OUTPUT->box_start('generalbox'); $mform->display(); echo $OUTPUT->box_end(); echo $OUTPUT->footer(); styles.css000064400000012760152265517660006626 0ustar00/* This file is part of Moodle - http://moodle.org/ Moodle is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Moodle is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Moodle. If not, see . */ /** * Wiki module style sheet * * @package mod-wiki-2.0 * @copyright 2009 Marc Alier, Jordi Piguillem marc.alier@upc.edu * @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu * * @author Jordi Piguillem * @author Marc Alier * @author David Jimenez * @author Josep Arus * @author Kenneth Riba * * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ .wiki_contentbox { width: 80%; margin: auto; min-width: 200px; min-height: 100px; } .wiki_previewbox { width: 50%; margin: auto; border: thin solid blue; } .wiki_button { margin: 5px; } .wiki_warning { color: red; } .emptycomments { color: red; display: inline; } .wiki-toc { border: 1px solid #bbb; background: #eee; margin: 16px; padding: 8px; } .wiki-toc-title { color: #666; font-size: 1.1em; font-variant: small-caps; text-align: center; } .wiki-toc-section { padding: 0; margin: 2px 8px; } .wiki-toc-section-2 { padding-left: 12px; } .wiki-toc-section-3 { padding-left: 24px; } .wiki_form-button { margin-left: 0%; } .wiki-upload-table { margin: 8px auto; clear: both; } .wiki-upload-table table { margin: auto; } .wiki-upload-table h3 { margin: 4px 0; text-align: center; } .wiki-upload-section { border: 1px solid #eee; width: 400px; margin: 8px auto; } .wiki-upload-section legend { font-weight: bold; font-size: 0.9em; margin-left: 16px; } .wiki-tags { text-align: right; } .wiki_modifieduser p { line-height: 35px; } .wiki_modifieduser img { border: thin solid black; } .wiki_restoreform, .wiki_deletecommentform { width: 10%; margin: auto; } .wiki_versionuser { float: left; } .wiki_diffuserleft, .wiki_diffuserright { font-weight: normal; padding-top: 1%; } .wiki_diffuserleft { float: right; } .wiki_diffuserright { float: left; } .wiki_compareheading { font-weight: normal; } .wiki_restore, .wiki_diffview, .wiki_difftime, .wiki_headingtime { font-size: 0.8em; font-weight: normal; } .wiki_difftime, .wiki_headingtime { font-style: oblique; text-align: center; } .wiki_diff_oldpaging { float: left; width: 40%; min-width: 200px; margin-left: 5%; } .wiki_diff_newpaging { float: right; width: 40%; min-width: 200px; margin-right: 5%; } .wiki_diff_old, .wiki_diff_new { float: left; min-width: 200px; width: 40%; } .wiki_difftable td { width: 50%; float: left; } .wiki_histdate { text-align: left; } .wiki_histnewdate { border-top: 1px dotted gray; } .ouw_deleted { background: #ffa; color: red; text-decoration: line-through; } .ouw_added { background: #cfc; color: red; } a.wiki_newentry:link, a.wiki_newentry:visited { color: red; font-style: italic; } .wiki_newentry a { color: red; font-style: italic; } .wiki_navigation_container { margin: 0 auto; } .wiki_navigation_from { float: left; width: 40%; min-width: 200px; margin-left: 5%; } .wiki_navigation_to { float: left; width: 40%; min-width: 200px; margin-right: 5%; } .wiki_headingtitle { text-align: center; } .wiki_clear { clear: both; } .wiki_right { text-align: right; } .wiki_index { text-align: right; } .notunderlined { text-decoration: none; } a.wiki_edit_section { font-size: 0.6em; position: relative; float: right; } .midpad { text-align: center; margin-top: 0.4em; margin-bottom: 0.4em; } .block_wiki_search ul { margin-top: 0.5em; margin-bottom: 3px; } .wiki-attachment:before { content: url("/mod/wiki/pix/attachment.png"); padding-right: 2px; } /** Print CSS */ #wiki_printable_content { text-align: left; } #wiki_printable_content a { color: black; } #wiki_printable_title { font-size: 2.2em; text-decoration: underline; } .wiki_diff_boxes { width: 100%; clear: both; } .wiki_diff_paging { width: 100%; clear: both; } .wiki_grayline { color: gray; } .wikisearchresults { padding-left: 50px; padding-top: 20px; } .wiki-diff-container { width: 95%; margin: 10px auto; } .wiki-diff-container .wiki-diff-leftside, .wiki-diff-container .wiki-diff-rightside { width: 49.5%; margin: 0; padding: 0; float: left; } .wiki-diff-container .wiki-diff-rightside { margin-left: 1%; } .wiki-diff-container .wiki-diff-heading, .wiki-diff-container .no-overflow { padding: 10px; border: 1px solid #ddd; } .wiki-diff-container .wiki-diff-rightside .wiki_diffversion { text-align: right; } .path-mod-wiki .printicon { background: url([[pix:t/print]]) no-repeat scroll 2px center transparent; padding-left: 20px; } #page-mod-wiki-prettyview .displayprinticon { text-align: right; } #page-mod-wiki-prettyview { background-image: none; } prettyview.php000064400000004567152265517660007532 0ustar00. /** * This file contains all necessary code to get a printable version of a wiki page * * @package mod_wiki * @copyright 2009 Marc Alier, Jordi Piguillem marc.alier@upc.edu * @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu * * @author Jordi Piguillem * @author Marc Alier * @author David Jimenez * @author Josep Arus * @author Kenneth Riba * * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once('../../config.php'); require_once($CFG->dirroot . '/mod/wiki/lib.php'); require_once($CFG->dirroot . '/mod/wiki/locallib.php'); require_once($CFG->dirroot . '/mod/wiki/pagelib.php'); $pageid = required_param('pageid', PARAM_INT); // Page ID if (!$page = wiki_get_page($pageid)) { throw new \moodle_exception('incorrectpageid', 'wiki'); } if (!$subwiki = wiki_get_subwiki($page->subwikiid)) { throw new \moodle_exception('incorrectsubwikiid', 'wiki'); } if (!$cm = get_coursemodule_from_instance("wiki", $subwiki->wikiid)) { throw new \moodle_exception('invalidcoursemodule'); } $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); if (!$wiki = wiki_get_wiki($subwiki->wikiid)) { throw new \moodle_exception('incorrectwikiid', 'wiki'); } require_course_login($course, true, $cm); if (!wiki_user_can_view($subwiki, $wiki)) { throw new \moodle_exception('cannotviewpage', 'wiki'); } $wikipage = new page_wiki_prettyview($wiki, $subwiki, $cm); $wikipage->set_page($page); $context = context_module::instance($cm->id); $other = array('prettyview' => true); wiki_page_view($wiki, $page, $course, $cm, $context, null, $other, $subwiki); $wikipage->print_header(); $wikipage->print_content(); $wikipage->print_footer(); renderer.php000064400000062715152265517660007115 0ustar00. /** * Moodle Wiki 2.0 Renderer * * @package mod_wiki * @copyright 2010 Dongsheng Cai * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); class mod_wiki_renderer extends plugin_renderer_base { public function page_index() { global $CFG; $output = ''; // Checking wiki instance if (!$wiki = wiki_get_wiki($this->page->cm->instance)) { return false; } // @TODO: Fix call to wiki_get_subwiki_by_group $gid = groups_get_activity_group($this->page->cm); $gid = !empty($gid) ? $gid : 0; if (!$subwiki = wiki_get_subwiki_by_group($this->page->cm->instance, $gid)) { return false; } $swid = $subwiki->id; $pages = wiki_get_page_list($swid); $selectoptions = array(); foreach ($pages as $page) { $selectoptions[$page->id] = format_string($page->title, true, array('context' => $this->page->context)); } $label = get_string('pageindex', 'wiki') . ': '; $select = new single_select(new moodle_url('/mod/wiki/view.php'), 'pageid', $selectoptions); $select->label = $label; return $this->output->container($this->output->render($select), 'wiki_index'); } public function search_result($records, $subwiki) { global $CFG; $table = new html_table(); $context = context_module::instance($this->page->cm->id); $strsearchresults = get_string('searchresult', 'wiki'); $totalcount = count($records); $html = $this->output->heading("$strsearchresults $totalcount", 3); foreach ($records as $page) { $table->head = array('title' => format_string($page->title) . ' (' . html_writer::link($CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $page->id, get_string('view', 'wiki')) . ')'); $table->align = array('title' => 'left'); $table->width = '100%'; $table->data = array(array(file_rewrite_pluginfile_urls(format_text($page->cachedcontent, FORMAT_HTML), 'pluginfile.php', $context->id, 'mod_wiki', 'attachments', $subwiki->id))); $table->colclasses = array('wikisearchresults'); $html .= html_writer::table($table); } $html = html_writer::tag('div', $html, array('class'=>'no-overflow')); return $this->output->container($html); } public function diff($pageid, $old, $new, $options = array()) { global $CFG; if (!empty($options['total'])) { $total = $options['total']; } else { $total = 0; } $diff1 = format_text($old->diff, FORMAT_HTML, array('overflowdiv'=>true)); $diff2 = format_text($new->diff, FORMAT_HTML, array('overflowdiv'=>true)); $strdatetime = get_string('strftimedatetime', 'langconfig'); $olduser = $old->user; $versionlink = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $old->id)); $restorelink = new moodle_url('/mod/wiki/restoreversion.php', array('pageid' => $pageid, 'versionid' => $old->id)); $userlink = new moodle_url('/user/view.php', array('id' => $olduser->id)); // view version link $oldversionview = ' '; $oldversionview .= html_writer::link($versionlink->out(false), get_string('view', 'wiki'), array('class' => 'wiki_diffview')); $oldversionview .= ' '; // restore version link $oldversionview .= html_writer::link($restorelink->out(false), get_string('restore', 'wiki'), array('class' => 'wiki_diffview')); // userinfo container $oldheading = $this->output->container_start('wiki_diffuserleft'); // username $oldheading .= html_writer::link($CFG->wwwroot . '/user/view.php?id=' . $olduser->id, fullname($olduser)) . ' '; // user picture $oldheading .= html_writer::link($userlink->out(false), $this->output->user_picture($olduser, array('popup' => true)), array('class' => 'notunderlined')); $oldheading .= $this->output->container_end(); // version number container $oldheading .= $this->output->container_start('wiki_diffversion'); $oldheading .= get_string('version') . ' ' . $old->version . $oldversionview; $oldheading .= $this->output->container_end(); // userdate container $oldheading .= $this->output->container_start('wiki_difftime'); $oldheading .= userdate($old->timecreated, $strdatetime); $oldheading .= $this->output->container_end(); $newuser = $new->user; $versionlink = new moodle_url('/mod/wiki/viewversion.php', array('pageid' => $pageid, 'versionid' => $new->id)); $restorelink = new moodle_url('/mod/wiki/restoreversion.php', array('pageid' => $pageid, 'versionid' => $new->id)); $userlink = new moodle_url('/user/view.php', array('id' => $newuser->id)); $newversionview = ' '; $newversionview .= html_writer::link($versionlink->out(false), get_string('view', 'wiki'), array('class' => 'wiki_diffview')); // new user info $newheading = $this->output->container_start('wiki_diffuserright'); $newheading .= $this->output->user_picture($newuser, array('popup' => true)); $newheading .= html_writer::link($userlink->out(false), fullname($newuser), array('class' => 'notunderlined')); $newheading .= $this->output->container_end(); // version $newheading .= $this->output->container_start('wiki_diffversion'); $newheading .= get_string('version') . ' ' . $new->version . $newversionview; $newheading .= $this->output->container_end(); // userdate $newheading .= $this->output->container_start('wiki_difftime'); $newheading .= userdate($new->timecreated, $strdatetime); $newheading .= $this->output->container_end(); $oldheading = html_writer::tag('div', $oldheading, array('class'=>'wiki-diff-heading header clearfix')); $newheading = html_writer::tag('div', $newheading, array('class'=>'wiki-diff-heading header clearfix')); $output = ''; $output .= html_writer::start_tag('div', array('class'=>'wiki-diff-container clearfix')); $output .= html_writer::tag('div', $oldheading.$diff1, array('class'=>'wiki-diff-leftside')); $output .= html_writer::tag('div', $newheading.$diff2, array('class'=>'wiki-diff-rightside')); $output .= html_writer::end_tag('div'); if (!empty($total)) { $output .= '
'; $output .= $this->output->container($this->diff_paging_bar(1, $new->version - 1, $old->version, $CFG->wwwroot . '/mod/wiki/diff.php?pageid=' . $pageid . '&comparewith=' . $new->version . '&', 'compare', false, true), 'wiki_diff_oldpaging'); $output .= $this->output->container($this->diff_paging_bar($old->version + 1, $total, $new->version, $CFG->wwwroot . '/mod/wiki/diff.php?pageid=' . $pageid . '&compare=' . $old->version . '&', 'comparewith', false, true), 'wiki_diff_newpaging'); $output .= '
'; } return $output; } /** * Prints a single paging bar to provide access to other versions * * @param int $minpage First page to be displayed in the bar * @param int $maxpage Last page to be displayed in the bar * @param int $page The page you are currently viewing * @param mixed $baseurl If this is a string then it is the url which will be appended with $pagevar, an equals sign and the page number. * If this is a moodle_url object then the pagevar param will be replaced by the page no, for each page. * @param string $pagevar This is the variable name that you use for the page number in your code (ie. 'tablepage', 'blogpage', etc) * @param bool $nocurr do not display the current page as a link * @param bool $return whether to return an output string or echo now * @return bool or string */ public function diff_paging_bar($minpage, $maxpage, $page, $baseurl, $pagevar = 'page', $nocurr = false) { $totalcount = $maxpage - $minpage; $maxdisplay = 2; $output = ''; if ($totalcount > 0) { $output .= '
'; $output .= get_string('version', 'wiki') . ':'; if ($page - $minpage > 0) { $pagenum = $page - 1; if (!is_a($baseurl, 'moodle_url')) { $output .= ' () '; } else { $output .= ' () '; } } if ($page - $minpage > 4) { $startpage = $page - 3; if (!is_a($baseurl, 'moodle_url')) { $output .= ' ' . $minpage . ' ...'; } else { $output .= ' ' . $minpage . ' ...'; } } else { $startpage = $minpage; } $currpage = $startpage; $displaycount = 0; while ($displaycount < $maxdisplay and $currpage <= $maxpage) { if ($page == $currpage && empty($nocurr)) { $output .= '  ' . $currpage; } else { if (!is_a($baseurl, 'moodle_url')) { $output .= '  ' . $currpage . ''; } else { $output .= '  ' . $currpage . ''; } } $displaycount++; $currpage++; } if ($currpage < $maxpage) { if (!is_a($baseurl, 'moodle_url')) { $output .= ' ...' . $maxpage . ' '; } else { $output .= ' ...' . $maxpage . ' '; } } else if ($currpage == $maxpage) { if (!is_a($baseurl, 'moodle_url')) { $output .= '  ' . $currpage . ''; } else { $output .= '  ' . $currpage . ''; } } $pagenum = $page + 1; if ($page != $maxpage) { if (!is_a($baseurl, 'moodle_url')) { $output .= '  ()'; } else { $output .= '  ()'; } } $output .= '
'; } return $output; } /** * @deprecated since Moodle 4.0 MDL-72413. Now handled in PAGE's activity header */ #[\core\attribute\deprecated(null, since: '4.3', mdl: 'MDL-72413', final: true)] public function wiki_info() { \core\deprecation::emit_deprecation([self::class, __FUNCTION__]); } public function tabs($page, $tabitems, $options) { $tabs = array(); $context = context_module::instance($this->page->cm->id); $pageid = null; if (!empty($page)) { $pageid = $page->id; } $selected = $options['activetab']; // make specific tab linked even it is active if (!empty($options['linkedwhenactive'])) { $linked = $options['linkedwhenactive']; } else { $linked = ''; } if (!empty($options['inactivetabs'])) { $inactive = $options['inactivetabs']; } else { $inactive = array(); } foreach ($tabitems as $tab) { if ($tab == 'edit' && !has_capability('mod/wiki:editpage', $context)) { continue; } if ($tab == 'comments' && !has_capability('mod/wiki:viewcomment', $context)) { continue; } if ($tab == 'files' && !has_capability('mod/wiki:viewpage', $context)) { continue; } if (($tab == 'view' || $tab == 'map' || $tab == 'history') && !has_capability('mod/wiki:viewpage', $context)) { continue; } if ($tab == 'admin' && !has_capability('mod/wiki:managewiki', $context)) { continue; } $link = new moodle_url('/mod/wiki/'. $tab. '.php', array('pageid' => $pageid)); if ($linked == $tab) { $tabs[] = new tabobject($tab, $link, get_string($tab, 'wiki'), '', true); } else { $tabs[] = new tabobject($tab, $link, get_string($tab, 'wiki')); } } return $this->tabtree($tabs, $selected, $inactive); } public function prettyview_link($page) { $html = ''; $link = new moodle_url('/mod/wiki/prettyview.php', array('pageid' => $page->id)); $html .= $this->output->container_start('wiki_right'); $html .= $this->output->action_link($link, get_string('prettyprint', 'wiki'), new popup_action('click', $link), array('class' => 'printicon')); $html .= $this->output->container_end(); return $html; } public function wiki_print_subwiki_selector($wiki, $subwiki, $page, $pagetype = 'view') { global $CFG, $USER; require_once($CFG->dirroot . '/user/lib.php'); $cm = get_coursemodule_from_instance('wiki', $wiki->id); switch ($pagetype) { case 'files': $baseurl = new moodle_url('/mod/wiki/files.php', array('wid' => $wiki->id, 'title' => $page->title, 'pageid' => $page->id)); break; case 'search': $search = optional_param('searchstring', null, PARAM_TEXT); $searchcontent = optional_param('searchwikicontent', 0, PARAM_INT); $baseurl = new moodle_url('/mod/wiki/search.php', array('cmid' => $cm->id, 'courseid' => $cm->course, 'searchstring' => $search, 'searchwikicontent' => $searchcontent)); break; case 'view': default: $baseurl = new moodle_url('/mod/wiki/view.php', array('wid' => $wiki->id, 'title' => $page->title)); break; } $context = context_module::instance($cm->id); // @TODO: A plenty of duplicated code below this lines. // Create private functions. switch (groups_get_activity_groupmode($cm)) { case NOGROUPS: if ($wiki->wikimode == 'collaborative') { // No need to print anything return; } else if ($wiki->wikimode == 'individual') { // We have private wikis here $view = has_capability('mod/wiki:viewpage', $context); $manage = has_capability('mod/wiki:managewiki', $context); // Only people with these capabilities can view all wikis if ($view && $manage) { // @TODO: Print here a combo that contains all users. $users = get_enrolled_users($context); $options = array(); foreach ($users as $user) { $options[$user->id] = fullname($user); } echo $this->output->container_start('wiki_right'); $name = 'uid'; $selected = $subwiki->userid; echo $this->output->single_select($baseurl, $name, $options, $selected, null, null, array('label' => get_string('user') . ':')); echo $this->output->container_end(); } return; } else { // error return; } case SEPARATEGROUPS: if ($wiki->wikimode == 'collaborative') { // We need to print a select to choose a course group echo $this->output->container_start('wiki_right'); groups_print_activity_menu($cm, $baseurl); echo $this->output->container_end(); return; } else if ($wiki->wikimode == 'individual') { // @TODO: Print here a combo that contains all users of that subwiki. $view = has_capability('mod/wiki:viewpage', $context); $manage = has_capability('mod/wiki:managewiki', $context); // Only people with these capabilities can view all wikis if ($view && $manage) { $users = get_enrolled_users($context); $options = array(); foreach ($users as $user) { $groups = groups_get_all_groups($cm->course, $user->id); if (!empty($groups)) { foreach ($groups as $group) { $options[$group->id][$group->name][$group->id . '-' . $user->id] = fullname($user); } } else { $name = get_string('notingroup', 'wiki'); $options[0][$name]['0' . '-' . $user->id] = fullname($user); } } } else { $group = groups_get_group($subwiki->groupid); if (!$group) { return; } $users = groups_get_members($subwiki->groupid); foreach ($users as $user) { $options[$group->id][$group->name][$group->id . '-' . $user->id] = fullname($user); } } echo $this->output->container_start('wiki_right'); $name = 'groupanduser'; $selected = $subwiki->groupid . '-' . $subwiki->userid; echo $this->output->single_select($baseurl, $name, $options, $selected, null, null, array('label' => get_string('user') . ':')); echo $this->output->container_end(); return; } else { // error return; } CASE VISIBLEGROUPS: if ($wiki->wikimode == 'collaborative') { // We need to print a select to choose a course group // moodle_url will take care of encoding for us echo $this->output->container_start('wiki_right'); groups_print_activity_menu($cm, $baseurl); echo $this->output->container_end(); return; } else if ($wiki->wikimode == 'individual') { $users = get_enrolled_users($context); $options = array(); foreach ($users as $user) { $groups = groups_get_all_groups($cm->course, $user->id); if (!empty($groups)) { foreach ($groups as $group) { $options[$group->id][$group->name][$group->id . '-' . $user->id] = fullname($user); } } else { $name = get_string('notingroup', 'wiki'); $options[0][$name]['0' . '-' . $user->id] = fullname($user); } } echo $this->output->container_start('wiki_right'); $name = 'groupanduser'; $selected = $subwiki->groupid . '-' . $subwiki->userid; echo $this->output->single_select($baseurl, $name, $options, $selected, null, null, array('label' => get_string('user') . ':')); echo $this->output->container_end(); return; } else { // error return; } default: // error return; } } function menu_map($pageid, $currentselect) { if (empty($currentselect)) { // The wiki uses digit number to match the options and 5 is the default one. $currentselect = 5; } $options = array('contributions', 'links', 'orphaned', 'pageindex', 'pagelist', 'updatedpages'); $items = array(); foreach ($options as $opt) { $items[] = get_string($opt, 'wiki'); } $selectoptions = array(); foreach ($items as $key => $item) { $selectoptions[$key + 1] = $item; } $select = new single_select(new moodle_url('/mod/wiki/map.php', array('pageid' => $pageid)), 'option', $selectoptions, $currentselect, null); $select->label = get_string('mapmenu', 'wiki') . ': '; return $this->output->container($this->output->render($select), 'midpad'); } public function wiki_files_tree($context, $subwiki) { return $this->render(new wiki_files_tree($context, $subwiki)); } public function render_wiki_files_tree(wiki_files_tree $tree) { if (empty($tree->dir['subdirs']) && empty($tree->dir['files'])) { $html = $this->output->box(get_string('nofilesavailable', 'repository')); } else { $htmlid = 'wiki_files_tree_'.uniqid(); $module = array('name'=>'mod_wiki', 'fullpath'=>'/mod/wiki/module.js'); $this->page->requires->js_init_call('M.mod_wiki.init_tree', array(false, $htmlid), false, $module); $html = '
'; $html .= $this->htmllize_tree($tree, $tree->dir); $html .= '
'; } return $html; } function menu_admin($pageid, $currentselect) { $options = array('removepages', 'deleteversions'); $items = array(); foreach ($options as $opt) { $items[] = get_string($opt, 'wiki'); } $selectoptions = array(); foreach ($items as $key => $item) { $selectoptions[$key + 1] = $item; } $select = new single_select(new moodle_url('/mod/wiki/admin.php', array('pageid' => $pageid)), 'option', $selectoptions, $currentselect, null); $select->label = get_string('adminmenu', 'wiki') . ': '; return $this->output->container($this->output->render($select), 'midpad'); } /** * Internal function - creates htmls structure suitable for YUI tree. */ protected function htmllize_tree($tree, $dir) { global $CFG; $yuiconfig = array(); $yuiconfig['type'] = 'html'; if (empty($dir['subdirs']) and empty($dir['files'])) { return ''; } $result = '
    '; foreach ($dir['subdirs'] as $subdir) { $image = $this->output->pix_icon(file_folder_icon(), $subdir['dirname'], 'moodle', array('class'=>'icon')); $result .= '
  • '.$image.' '.s($subdir['dirname']).'
    '.$this->htmllize_tree($tree, $subdir).'
  • '; } foreach ($dir['files'] as $file) { $url = file_encode_url("$CFG->wwwroot/pluginfile.php", '/'.$tree->context->id.'/mod_wiki/attachments/' . $tree->subwiki->id . '/'. $file->get_filepath() . $file->get_filename(), true); $filename = $file->get_filename(); $image = $this->output->pix_icon(file_file_icon($file), $filename, 'moodle', array('class'=>'icon')); $result .= '
  • '.$image.' '.html_writer::link($url, $filename).'
  • '; } $result .= '
'; return $result; } /** * Renders the action bar. * * @param \mod_wiki\output\action_bar $actionbar * @return string The HTML output */ public function render_action_bar(\mod_wiki\output\action_bar $actionbar): string { $data = $actionbar->export_for_template($this); return $this->render_from_template('mod_wiki/action_bar', $data); } } class wiki_files_tree implements renderable { public $context; public $dir; public $subwiki; public function __construct($context, $subwiki) { $fs = get_file_storage(); $this->context = $context; $this->subwiki = $subwiki; $this->dir = $fs->get_area_tree($context->id, 'mod_wiki', 'attachments', $subwiki->id); } } db/tag.php000064400000002135152265517660006435 0ustar00. /** * Tag areas in component mod_wiki * * @package mod_wiki * @copyright 2015 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $tagareas = array( array( 'itemtype' => 'wiki_pages', 'component' => 'mod_wiki', 'callback' => 'mod_wiki_get_tagged_pages', 'callbackfile' => '/mod/wiki/locallib.php', ), ); db/services.php000064400000011321152265517660007502 0ustar00. /** * Wiki external functions and service definitions. * * @package mod_wiki * @category external * @copyright 2015 Dani Palou * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @since Moodle 3.1 */ $functions = array( 'mod_wiki_get_wikis_by_courses' => array( 'classname' => 'mod_wiki_external', 'methodname' => 'get_wikis_by_courses', 'description' => 'Returns a list of wiki instances in a provided set of courses, if ' . 'no courses are provided then all the wiki instances the user has access to will be returned.', 'type' => 'read', 'capabilities' => 'mod/wiki:viewpage', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ), 'mod_wiki_view_wiki' => array( 'classname' => 'mod_wiki_external', 'methodname' => 'view_wiki', 'description' => 'Trigger the course module viewed event and update the module completion status.', 'type' => 'write', 'capabilities' => 'mod/wiki:viewpage', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ), 'mod_wiki_view_page' => array( 'classname' => 'mod_wiki_external', 'methodname' => 'view_page', 'description' => 'Trigger the page viewed event and update the module completion status.', 'type' => 'write', 'capabilities' => 'mod/wiki:viewpage', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ), 'mod_wiki_get_subwikis' => array( 'classname' => 'mod_wiki_external', 'methodname' => 'get_subwikis', 'description' => 'Returns the list of subwikis the user can see in a specific wiki.', 'type' => 'read', 'capabilities' => 'mod/wiki:viewpage', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ), 'mod_wiki_get_subwiki_pages' => array( 'classname' => 'mod_wiki_external', 'methodname' => 'get_subwiki_pages', 'description' => 'Returns the list of pages for a specific subwiki.', 'type' => 'read', 'capabilities' => 'mod/wiki:viewpage', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ), 'mod_wiki_get_subwiki_files' => array( 'classname' => 'mod_wiki_external', 'methodname' => 'get_subwiki_files', 'description' => 'Returns the list of files for a specific subwiki.', 'type' => 'read', 'capabilities' => 'mod/wiki:viewpage', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ), 'mod_wiki_get_page_contents' => array( 'classname' => 'mod_wiki_external', 'methodname' => 'get_page_contents', 'description' => 'Returns the contents of a page.', 'type' => 'read', 'capabilities' => 'mod/wiki:viewpage', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ), 'mod_wiki_get_page_for_editing' => array( 'classname' => 'mod_wiki_external', 'methodname' => 'get_page_for_editing', 'description' => 'Locks and retrieves info of page-section to be edited.', 'type' => 'write', 'capabilities' => 'mod/wiki:editpage', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ), 'mod_wiki_new_page' => array( 'classname' => 'mod_wiki_external', 'methodname' => 'new_page', 'description' => 'Create a new page in a subwiki.', 'type' => 'write', 'capabilities' => 'mod/wiki:editpage', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ), 'mod_wiki_edit_page' => array( 'classname' => 'mod_wiki_external', 'methodname' => 'edit_page', 'description' => 'Save the contents of a page.', 'type' => 'write', 'capabilities' => 'mod/wiki:editpage', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ) ); db/install.php000064400000000071152265517660007325 0ustar00. /** * Plugin capabilities * * @package mod_wiki * @author Jordi Piguillem * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $capabilities = array( 'mod/wiki:addinstance' => array( 'riskbitmask' => RISK_XSS, 'captype' => 'write', 'contextlevel' => CONTEXT_COURSE, 'archetypes' => array( 'editingteacher' => CAP_ALLOW, 'manager' => CAP_ALLOW ), 'clonepermissionsfrom' => 'moodle/course:manageactivities' ), 'mod/wiki:viewpage' => array( 'captype' => 'read', 'contextlevel' => CONTEXT_MODULE, 'archetypes' => array( 'guest' => CAP_ALLOW, 'frontpage' => CAP_ALLOW, 'student' => CAP_ALLOW, 'teacher' => CAP_ALLOW, 'editingteacher' => CAP_ALLOW, 'manager' => CAP_ALLOW ) ), 'mod/wiki:editpage' => array( 'riskbitmask' => RISK_SPAM, 'captype' => 'write', 'contextlevel' => CONTEXT_MODULE, 'archetypes' => array( 'student' => CAP_ALLOW, 'teacher' => CAP_ALLOW, 'editingteacher' => CAP_ALLOW, 'manager' => CAP_ALLOW ) ), 'mod/wiki:createpage' => array( 'riskbitmask' => RISK_SPAM, 'captype' => 'write', 'contextlevel' => CONTEXT_MODULE, 'archetypes' => array( 'student' => CAP_ALLOW, 'teacher' => CAP_ALLOW, 'editingteacher' => CAP_ALLOW, 'manager' => CAP_ALLOW ) ), 'mod/wiki:viewcomment' => array( 'captype' => 'read', 'contextlevel' => CONTEXT_MODULE, 'archetypes' => array( 'student' => CAP_ALLOW, 'teacher' => CAP_ALLOW, 'editingteacher' => CAP_ALLOW, 'manager' => CAP_ALLOW ) ), 'mod/wiki:editcomment' => array( 'riskbitmask' => RISK_SPAM, 'captype' => 'write', 'contextlevel' => CONTEXT_MODULE, 'archetypes' => array( 'student' => CAP_ALLOW, 'teacher' => CAP_ALLOW, 'editingteacher' => CAP_ALLOW, 'manager' => CAP_ALLOW ) ), 'mod/wiki:managecomment' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_MODULE, 'archetypes' => array( 'teacher' => CAP_ALLOW, 'editingteacher' => CAP_ALLOW, 'manager' => CAP_ALLOW ) ), 'mod/wiki:managefiles' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_MODULE, 'archetypes' => array( 'teacher' => CAP_ALLOW, 'editingteacher' => CAP_ALLOW, 'manager' => CAP_ALLOW ) ), 'mod/wiki:overridelock' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_MODULE, 'archetypes' => array( 'teacher' => CAP_ALLOW, 'editingteacher' => CAP_ALLOW, 'manager' => CAP_ALLOW ) ), 'mod/wiki:managewiki' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_MODULE, 'archetypes' => array( 'teacher' => CAP_ALLOW, 'editingteacher' => CAP_ALLOW, 'manager' => CAP_ALLOW ) ), ); db/upgrade.php000064400000003631152265517660007313 0ustar00. /** * This file keeps track of upgrades to the wiki module * * Sometimes, changes between versions involve * alterations to database structures and other * major things that may break installations. * * The upgrade function in this file will attempt * to perform all the necessary actions to upgrade * your older installation to the current version. * * @package mod_wiki * @copyright 2009 Marc Alier, Jordi Piguillem marc.alier@upc.edu * @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu * * @author Jordi Piguillem * * @license http://www.gnu.org/copyleft/gpl.html GNU Public License * */ function xmldb_wiki_upgrade($oldversion) { // Automatically generated Moodle v4.2.0 release upgrade line. // Put any upgrade step following this. // Automatically generated Moodle v4.3.0 release upgrade line. // Put any upgrade step following this. // Automatically generated Moodle v4.4.0 release upgrade line. // Put any upgrade step following this. // Automatically generated Moodle v4.5.0 release upgrade line. // Put any upgrade step following this. // Automatically generated Moodle v5.0.0 release upgrade line. // Put any upgrade step following this. return true; } db/install.xml000064400000020626152265517660007346 0ustar00
lang/en/deprecated.txt000064400000000025152265517660010744 0ustar00tagsdeleted,mod_wiki lang/en/wiki.php000064400000043563152265517660007575 0ustar00old} with version {$a->new}'; $string['contributions'] = 'Contributions'; $string['contributions_help'] = 'List of pages that you have edited.'; $string['createcomment'] = 'Creating comment'; $string['creating'] = 'Creating a wiki page'; $string['createpage'] = 'Create page'; $string['createddate'] = 'Created: {$a->date} by {$a->username}'; $string['creole'] = 'Creole'; $string['defaultformat'] = 'Default format'; $string['defaultformat_help'] = 'This setting determines the default format used when editing wiki pages. * HTML - The HTML editor is available * Creole - A common wiki markup language for which a small edit toolbar is available * Nwiki - Mediawiki-like markup language used in the contributed Nwiki module'; $string['deleteallpages'] = 'All wiki pages'; $string['deletecomment'] = 'Deleting comment'; $string['deletecommentcheck'] = 'Delete comment'; $string['deletecommentcheckfull'] = 'Are you sure you want to delete the comment?'; $string['deleteupload'] = 'Delete'; $string['deletedbegins'] = 'Deleted begins'; $string['deletedends'] = 'Deleted ends'; $string['deleteversions'] = 'Delete page versions'; $string['addedbegins'] = 'added begins'; $string['addedends'] = 'added ends'; $string['diff'] = 'Diff'; $string['diff_help'] = 'Selected versions of the page may be compared in order to find the differences.'; $string['edit'] = 'Edit'; $string['editcomment'] = 'Edit comment'; $string['editblocks'] = 'Turn edit blocks on'; $string['editfiles'] = 'Edit wiki files'; $string['editing'] = 'Editing wiki page'; $string['editingcomment'] = 'Editing comment'; $string['editingpage'] = 'Editing this page \'{$a}\''; $string['editsection'] = 'edit'; $string['eventdiffviewed'] = 'Wiki diff viewed'; $string['eventhistoryviewed'] = 'Wiki history viewed'; $string['eventmapviewed'] = 'Wiki page map viewed'; $string['eventpagedeleted'] = 'Wiki page deleted'; $string['eventpagecreated'] = 'Wiki page created'; $string['eventpagelocksdeleted'] = 'Wiki page locks deleted'; $string['eventpageviewed'] = 'Wiki page viewed'; $string['eventpageupdated'] = 'Wiki page updated'; $string['eventpageversiondeleted'] = 'Wiki page version deleted'; $string['eventversionrestored'] = 'Wiki version restored'; $string['eventversionviewed'] = 'Wiki page version viewed'; $string['files'] = 'Files'; $string['filenotuploadederror'] = 'File \'{$a}\' could not be uploaded correctly.'; $string['filtername'] = 'Wiki auto-linking'; $string['firstpagetitle'] = 'First page name'; $string['firstpagetitle_help'] = 'Title of the first page of the wiki. Once the wiki is created, the title can no longer be changed.'; $string['forceformat'] = 'Force format'; $string['forceformat_help'] = 'If the format is forced (checkbox ticked), there is no option to choose a format when editing a wiki page.'; $string['format'] = 'Format'; $string['format_help'] = '* HTML - The HTML editor is available * Creole - A common wiki markup language for which a small edit toolbar is available * Nwiki - Mediawiki-like markup language used in the contributed Nwiki module'; $string['formathtml'] = 'HTML format'; $string['formathtml_help'] = 'The HTML editor may be used for formatting content. To create a new page, type the new page name enclosed in double square brackets, for example [[Page 2]].'; $string['formatcreole'] = 'Creole format'; $string['formatcreole_help'] = 'Creole is a common wiki markup language with an edit toolbar for inserting appropriate markup. To create a new page, type the new page name enclosed in double square brackets, for example [[Page 2]].'; $string['formatcreole_link'] = 'mod/wiki/creole'; $string['formatnwiki'] = 'NWiki format'; $string['formatnwiki_help'] = 'Nwiki is the Mediawiki-like markup language used in the contributed Nwiki module. To create a new page, type the new page name enclosed in double square brackets, for example [[Page 2]].'; $string['formatnwiki_link'] = 'mod/wiki/nwiki'; $string['history'] = 'History'; $string['history_help'] = 'The history lists links to previous versions of the page.'; $string['html'] = 'HTML'; $string['incorrectdeleteversions'] = "Page versions provided for deletion are incorrect."; $string['incorrectpageid'] = 'Page ID is incorrect.'; $string['incorrectsubwikiid'] = 'Subwiki ID is incorrect.'; $string['incorrectwikiid'] = 'Wiki ID is incorrect.'; $string['indicator:cognitivedepth'] = 'Wiki cognitive'; $string['indicator:cognitivedepth_help'] = 'This indicator is based on the cognitive depth reached by the student in a Wiki activity.'; $string['indicator:cognitivedepthdef'] = 'Wiki cognitive'; $string['indicator:cognitivedepthdef_help'] = 'The participant has reached this percentage of the cognitive engagement offered by the Wiki activities during this analysis interval (Levels = No view, View, Submit)'; $string['indicator:cognitivedepthdef_link'] = 'Learning_analytics_indicators#Cognitive_depth'; $string['indicator:socialbreadth'] = 'Wiki social'; $string['indicator:socialbreadth_help'] = 'This indicator is based on the social breadth reached by the student in a Wiki activity.'; $string['indicator:socialbreadthdef'] = 'Wiki social'; $string['indicator:socialbreadthdef_help'] = 'The participant has reached this percentage of the social engagement offered by the Wiki activities during this analysis interval (Levels = No participation, Participant alone, Participant with others)'; $string['indicator:socialbreadthdef_link'] = 'Learning_analytics_indicators#Social_breadth'; $string['insertcomment'] = 'Insert comment'; $string['insertimage'] = 'Insert an image...'; $string['insertimage_help'] = 'This drop-down list will insert an image to the wiki editor. If you need to add more images to the wiki, please use "Files" tab.'; $string['invalidlock'] = 'This page is already locked by another user.'; $string['invalidparameters'] = 'Invalid parameters have been given.'; $string['invalidsection'] = 'Invalid section.'; $string['invalidsesskey'] = 'Your session has most likely timed out. Please make a note of your edit then log in again.'; $string['individualpagedoesnotexist'] = 'Individual wiki page doesn\'t exist'; $string['javascriptdisabledlocks'] = 'Javascript is disabled on your browser and locks are not working. The changes you make may not be saved correctly.'; $string['lockingajaxtimeout'] = 'Edit page locking refresh time'; $string['lockingtimeout'] = 'Locking timeout'; $string['links'] = 'Links'; $string['listall'] = 'List all'; $string['listorphan'] = 'List orphan'; $string['map'] = 'Map'; $string['mapmenu'] = 'Map menu'; $string['migrationfinished'] = 'Migration finished successfully'; $string['migrationfinishednowikis'] = 'Migration finished, no wikis were migrated'; $string['missingpages'] = 'Pages without content'; $string['modified'] = 'Modified'; $string['modulename'] = 'Wiki'; $string['modulename_help'] = 'The wiki activity module enables participants to add and edit a collection of web pages. A wiki can be collaborative, with everyone being able to edit it, or individual, where everyone has their own wiki which only they can edit. A history of previous versions of each page in the wiki is kept, listing the edits made by each participant. Wikis have many uses, such as * For group lecture notes or study guides * For members of a faculty to plan a scheme of work or meeting agenda together * For students to collaboratively author an online book, creating content on a topic set by their tutor * For collaborative storytelling or poetry creation, where each participant writes a line or verse * As a personal journal for examination notes or revision (using an individual wiki)'; $string['modulename_link'] = 'mod/wiki/view'; $string['modulenameplural'] = 'Wikis'; $string['navigation'] = 'Navigation'; $string['navigationfrom'] = 'This page comes from'; $string['navigationfrom_help'] = 'The wiki pages linking to this page'; $string['navigationto'] = 'This page goes to'; $string['navigationto_help'] = 'Links to other pages'; $string['newpage'] = 'New'; $string['newpagehdr'] = 'New page'; $string['newpagetitle'] = 'New page title'; $string['noattachments'] = 'No files attached'; $string['nocontent'] = 'There is no content for this page'; $string['nocontribs'] = 'You have no contributions in this wiki'; $string['nocomments'] = 'There are no comments'; $string['nocreatepermission'] = 'Create page permission needed'; $string['noeditcommentpermission'] = 'Edit comment permission needed'; $string['noeditpermission'] = 'Edit page permission needed'; $string['nofrompages'] = 'There are no links to this page'; $string['nohistory'] = 'There is no history for this page'; $string['nomanagecommentpermission'] = 'Manage comments permission needed'; $string['nomanagewikipermission'] = 'Manage wiki permission needed'; $string['noorphanedpages'] = 'There are no orphaned pages'; $string['nooverridelockpermission'] = 'Override lock permission needed'; $string['norated']='This page has not been rated yet, be the first!'; $string['norating'] = 'No rating'; $string['nosearchresults'] = 'No results'; $string['noteditblocks'] = 'Turn edit blocks off'; $string['notingroup'] = 'Not in group'; $string['notopages'] = 'This page does not link to other pages'; $string['notmigrated'] = 'This wiki has not been migrated yet. Please contact your administrator.'; $string['noupdatedpages'] = 'There are no updated pages'; $string['noviewcommentpermission'] = 'View comments permission needed'; $string['noviewpagepermission'] = 'View page permission needed'; $string['nwiki'] = 'NWiki'; $string['oldversion'] = 'Old version'; $string['orphaned'] = 'Orphaned pages'; $string['orphaned_help'] = 'List of pages that are not linked from other page.'; $string['overridelocks'] = 'Override locks'; $string['overridinglocks'] = 'Overriding locks...'; $string['page-mod-wiki-x'] = 'Any wiki module page'; $string['page-mod-wiki-view'] = 'Wiki module main page'; $string['page-mod-wiki-comments'] = 'Wiki module comments page'; $string['page-mod-wiki-history'] = 'Wiki history page'; $string['page-mod-wiki-map'] = 'Wiki map page'; $string['pageexists'] = 'This page already exists.'; $string['pageindex'] = 'Page Index'; $string['pageindex_help'] = 'This wiki\'s page tree'; $string['pageislocked'] = 'Someone is editing this page right now. Try to edit it in a few minutes.'; $string['pagelist'] = 'Page list'; $string['pagelist_help'] = 'Page list categorized by alphabetical order'; $string['pagename'] = 'Page name'; $string['peerreview'] = 'Peer review'; $string['pluginadministration'] = 'Wiki administration'; $string['pluginname'] = 'Wiki'; $string['prettyprint'] = 'Printer-friendly version'; $string['print'] = 'Print'; $string['privacy:metadata:core_comment'] = 'Comments on wiki page'; $string['privacy:metadata:core_files'] = 'Files attached to subwikis'; $string['privacy:metadata:core_tag'] = 'Tags associated with wiki pages'; $string['privacy:metadata:wiki_locks'] = 'Temporary storage for wiki edit locks'; $string['privacy:metadata:wiki_locks:userid'] = 'User who locked a page'; $string['privacy:metadata:wiki_locks:sectionname'] = 'Name of the locked page section'; $string['privacy:metadata:wiki_locks:lockedat'] = 'Date when locked'; $string['privacy:metadata:wiki_pages'] = 'Information about wiki pages'; $string['privacy:metadata:wiki_pages:userid'] = 'Last user who edited the page'; $string['privacy:metadata:wiki_pages:title'] = 'Name of the page'; $string['privacy:metadata:wiki_pages:cachedcontent'] = 'Cached content in HTML format'; $string['privacy:metadata:wiki_pages:timecreated'] = 'Time when page was first created'; $string['privacy:metadata:wiki_pages:timemodified'] = 'Time when page was last modified'; $string['privacy:metadata:wiki_pages:timerendered'] = 'Time when page was last rendered'; $string['privacy:metadata:wiki_pages:pageviews'] = 'Number of times page was viewed'; $string['privacy:metadata:wiki_pages:readonly'] = 'Whether a page is read-only'; $string['privacy:metadata:wiki_subwikis'] = 'Information about subwikis (in case of group or individual mode)'; $string['privacy:metadata:wiki_subwikis:userid'] = 'User who owns a subwiki (for individual wikis)'; $string['privacy:metadata:wiki_subwikis:groupid'] = 'Group that owns a subwiki'; $string['privacy:metadata:wiki_versions'] = 'Information about wiki pages history'; $string['privacy:metadata:wiki_versions:userid'] = 'User who created revision'; $string['privacy:metadata:wiki_versions:content'] = 'Revision content'; $string['privacy:metadata:wiki_versions:contentformat'] = 'Revision content format'; $string['privacy:metadata:wiki_versions:version'] = 'Version number'; $string['privacy:metadata:wiki_versions:timecreated'] = 'Time when revision was created'; $string['previewwarning'] = 'This is a preview. Changes have not been saved yet.'; $string['rated']='You rated this page as a {$a}'; $string['rating']='Rating'; $string['ratingmode'] = 'Rating mode'; $string['reparsetimeout'] = 'Reparsing default timeout'; $string['repeatedsection'] = 'Wiki error: Section name cannot be repeated \'{$a}\''; $string['restore'] = 'Restore'; $string['removeallwikitags'] = 'All wiki tags'; $string['removepages'] = 'Remove pages'; $string['restoreconfirm'] = 'Are you sure you want to restore version #{$a}?'; $string['restoreerror'] = 'Version #{$a} could not be restored'; $string['restorethis'] = 'Restore this version'; $string['restoreversion'] = 'Restore old version'; $string['restoring'] = 'Restoring version #{$a}'; $string['return'] = 'Go back'; $string['save'] = 'Save'; $string['saving'] = 'Saving wiki page'; $string['savingerror'] = 'Saving error'; $string['search:activity'] = 'Wiki - activity information'; $string['search:collaborative_page'] = 'Wiki - collaborative pages'; $string['searchcontent'] = 'Search in page content'; $string['searchresult'] = 'Search results:'; $string['searchterms'] = 'Search terms'; $string['searchwikis'] = 'Search wikis'; $string['special'] = 'Special'; $string['tableofcontents'] = 'Table of contents'; $string['tagarea_wiki_pages'] = 'Wiki pages'; $string['teacherrating'] = 'Teacher rating'; $string['timesrating'] = 'This page has been rated {$a->c} times with an average of: {$a->s}'; $string['updatedpages'] = "Updated pages"; $string['updatedpages_help'] = "Recently updated wiki pages"; $string['updatedwikipages'] = "Updated wiki pages"; $string['upload'] = "Upload & Delete"; $string['uploadname'] = "Filename"; $string['uploadactions'] = "Actions"; $string['uploadtitle'] = 'Attach files'; $string['uploadfiletitle'] = 'Attachments'; $string['versionerror'] = 'Version ID does not exist'; $string['versionnum'] = 'Version #{$a}'; $string['version'] = 'Version'; $string['view'] = 'View'; $string['viewallhistory'] = 'View all history'; $string['viewperpage'] = 'Show {$a} versions per page'; $string['viewversion'] = 'Viewing page version #{$a}'; $string['viewcurrent'] = 'Current version'; $string['wiki'] = 'Wiki'; $string['wikiattachments'] = 'Wiki attachments'; $string['wikiboldtext'] = 'Bold text'; $string['wikiexternalurl'] = 'External URL'; $string['wikifiletable'] = 'Uploaded file list'; $string['wikifiles'] = 'Wiki files'; $string['wikiheader'] = 'Level {$a} Header'; $string['wikihr'] = 'Horizontal rule'; $string['wikiimage'] = 'Image'; $string['wikiinternalurl'] = 'Internal link'; $string['wikiintro'] = 'Description'; $string['wikiitalictext'] = 'Italic text'; $string['wikilockingsettings'] = 'Locking and reparsing timeouts'; $string['wikimode'] = 'Wiki mode'; $string['wikimode_help'] = 'The wiki mode determines whether everyone can edit the wiki - a collaborative wiki - or whether everyone has their own wiki which only they can edit - an individual wiki.'; $string['wikimodecollaborative'] = 'Collaborative wiki'; $string['wikimodeindividual'] = 'Individual wiki'; $string['wikiname'] = 'Wiki name'; $string['wikinowikitext'] = 'No wiki text'; $string['wikiorderedlist'] = 'Ordered list'; $string['wikisettings'] = 'Wiki settings'; $string['wikiunorderedlist'] = 'Unordered list'; $string['wiki:addinstance'] = 'Add a new wiki'; $string['wiki:createpage'] = 'Create new wiki pages'; $string['wiki:editcomment'] = 'Add comments to pages'; $string['wiki:editpage'] = 'Edit wiki pages'; $string['wiki:managecomment'] = 'Manage wiki comments'; $string['wiki:managewiki'] = 'Manage wiki settings'; $string['wiki:managefiles'] = 'Manage wiki files'; $string['wiki:overridelock'] = 'Override wiki locks'; $string['wiki:viewcomment'] = 'View page comments'; $string['wiki:viewpage'] = 'View wiki pages'; $string['wikipages'] = 'Wiki pages'; $string['wrongversionlock'] = 'Another user has edited this page while you were editing and your content is obsolete.'; $string['wrongversionsave'] = 'Another user has created a version while you were editing and you have overwritten his changes, check the page history.'; // Deprecated since Moodle 4.5. $string['tagsdeleted'] = 'Wiki tags have been deleted'; parser/utils.php000064400000005302152265517660007730 0ustar00 $link, 'url' => "http://".$l); } /** * Default table generator */ public static function wiki_parser_table_callback($table) { $html = ""; $headers = $table[0]; $columncount = count($headers); $headerhtml = ""; foreach($headers as $h) { $text = trim($h[1]); if($h[0] == 'header') { $headerhtml .= "\n".parser_utils::h('th', $text)."\n"; $hasheaders = true; } else if($h[0] == 'normal'){ $headerhtml .= "\n".parser_utils::h("td", $text)."\n"; } } $headerhtml = "\n".parser_utils::h('tr', $headerhtml)."\n"; $bodyhtml = ""; if(isset($hasheaders)) { $html = "\n".parser_utils::h('thead', $headerhtml)."\n"; } else { $bodyhtml .= $headerhtml; } array_shift($table); foreach($table as $row) { $htmlrow = ""; for($i = 0; $i < $columncount; $i++) { $text = ""; if(!isset($row[$i])) { $htmlrow .= "\n".parser_utils::h('td', $text)."\n"; } else { $text = trim($row[$i][1]); if($row[$i][0] == 'header') { $htmlrow .= "\n".parser_utils::h('th', $text)."\n"; } else if($row[$i][0] == 'normal'){ $htmlrow .= "\n".parser_utils::h('td', $text)."\n"; } } } $bodyhtml .= "\n".parser_utils::h('tr', $htmlrow)."\n"; } $html .= "\n".parser_utils::h('tbody', $bodyhtml)."\n"; return "\n".parser_utils::h('table', $html)."\n"; } /** * Default path converter */ public static function wiki_parser_real_path($url) { return $url; } } parser/markups/nwiki.php000064400000017555152265517660011410 0ustar00 array( 'expression' => "/^(.*?)<\/nowiki>/ims", 'tags' => array(), 'token' => array('', '') ), 'header' => array( 'expression' => "/^\ *(={1,6})\ *(.+?)(={1,6})\ *$/ims", 'tags' => array(), //none 'token' => '=' ), 'line_break' => array( 'expression' => "/^-{3,4}\s*$/im", 'tags' => array(), 'token' => '---' ), 'desc_list' => array( 'expression' => "/(?:^.+?\:.+?\;\n)+/ims", 'tags' => array(), 'token' => array(':', ';'), 'tag' => 'dl' ), 'table' => array( 'expression' => "/\{\|(.+?)\|\}/ims" ), 'tab_paragraph' => array( 'expression' => "/^(\:+)(.+?)$/ims", 'tag' => 'p' ), 'list' => array( 'expression' => "/^((?:\ *[\*|#]{1,5}\ *.+?)+)(\n\s*(?:\n|<(?:h\d|pre|table|tbody|thead|tr|th|td|ul|li|ol|hr)\ *\/?>))/ims", 'tags' => array(), 'token' => array('*', '#') ), 'paragraph' => array( 'expression' => "/^\ *((?:<(?!\ *\/?(?:h\d|pre|table|tbody|thead|tr|th|td|ul|li|ol|hr)\ *\/?>)|[^<\s]).+?)\n\s*\n/ims", //not specified -> all tags (null or unset) 'tag' => 'p' ) ); protected $tagrules = array( 'nowiki' => array( 'expression' => "/(.*?)<\/nowiki>/is", 'token' => array('', '') ), 'image' => array( 'expression' => "/\[\[image:(.+?)\|(.+?)\]\]/is", 'token' => array("[[image:", "|alt]]") ), 'attach' => array( 'expression' => "/\[\[attach:(.+?)\]\]/is", 'token' => array("[[attach:", "|name]]") ), 'link' => array( 'expression' => "/\[\[(.+?)\]\]/is", 'tag' => 'a', 'token' => array("[[", "]]") ), 'url_tag' => array( 'expression' => "/\[(.+?)\]/is", 'tag' => 'a', 'token' => array("[", "]") ), 'url' => array( 'expression' => "/(? 'a', 'token' => 'http://' ), 'italic' => array( 'expression' => "/\'{3}(.+?)(\'{3}(?:\'{2})?)/is", 'tag' => 'em', 'token' => array("'''", "'''") ), 'bold' => array( 'expression' => "/\'{2}(.+?)\'{2}/is", 'tag' => 'strong', 'token' => array("''", "''") ) ); protected function after_parsing() { parent::after_parsing(); } /** * Block hooks */ protected function header_block_rule($match) { if($match[1] != $match[3]) { return $match[0]; } $num = strlen($match[1]); return $this->generate_header($match[2], $num); } protected function table_block_rule($match) { $rows = explode("\n|-", $match[1]); $table = array(); foreach($rows as $r) { $colsendline = explode("\n", $r); $cols = array(); foreach($colsendline as $ce) { $cols = array_merge($cols, $this->get_table_cells($ce)); } if(!empty($cols)) { $table[] = $cols; } } return $this->generate_table($table); } private function get_table_cells($string) { $string = ltrim($string); $type = (!empty($string) && $string[0] == "!") ? 'header' : 'normal'; $string = substr($string, 1); if(empty($string)) { $normalcells = array(); } else { $normalcells = explode("||", $string); } $cells = array(); foreach($normalcells as $nc) { $headercells = explode("!!", $nc); $countheadercells = count($headercells); for($i = 0; $i < $countheadercells; $i++) { $cells[] = array($type, $headercells[$i]); $type = 'header'; } $type = 'normal'; } return $cells; } protected function tab_paragraph_block_rule($match) { $num = strlen($match[1]); $text = $match[2]; $html = ""; for($i = 0; $i < $num - 1; $i++) { $html = parser_utils::h('p', $html, array('class' => 'wiki_tab_paragraph')); } return parser_utils::h('p', $text, array('class' => 'wiki_tab_paragraph')); } protected function desc_list_block_rule($match) { preg_match_all("/^(.+?)\:(.+?)\;$/ims", $match[0], $listitems, PREG_SET_ORDER); $list = ""; foreach($listitems as $li) { $term = $li[1]; $this->rules($term); $description = $li[2]; $this->rules($description); $list .= parser_utils::h('dt', $term).parser_utils::h('dd', $description); } return $list; } /** * Tag functions */ /** * Bold and italic similar to creole... */ protected function italic_tag_rule($match) { $text = $match[1]; if(strlen($match[2]) == 5) { $text .= "''"; } $this->rules($text, array('only' => array('bold'))); if(strpos($text, "''") !== false) { $text = str_replace("''", $this->protect("''"), $text); } return array($text, array()); } /** * Link tag functions */ protected function link_tag_rule($match) { return $this->format_link($match[1]); } protected function url_tag_tag_rule($match) { $text = trim($match[1]); if(preg_match("/(.+?)\|(.+)/is", $text, $matches)) { $link = $matches[1]; $text = $matches[2]; } else if(preg_match("/(.+?)\ (.+)/is", $text, $matches)) { $link = $matches[1]; $text = $matches[2]; } else { $link = $text; } return array($this->protect($text), array('href' => $this->protect($link))); } protected function url_tag_rule($match) { $url = $this->protect($match[1]); $options = array('href' => $url); return array($url, $options); } /** * Attachments & images */ protected function image_tag_rule($match) { return $this->format_image($match[1], $match[2]); } protected function attach_tag_rule($match) { $parts = explode("|", $match[1]); $url = array_shift($parts); if(count($parts) > 0) { $text = array_shift($parts); } $extension = substr($url, strrpos($url, ".")); $text = empty($text) ? $url : $text; $imageextensions = array('jpg', 'jpeg', 'png', 'bmp', 'gif', 'tif'); if(in_array($extension, $imageextensions)) { $align = 'left'; if(count($parts) > 0) { switch(strtolower($text)) { case 'right': $align = 'right'; break; case 'center': $align = 'center'; break; default: $align = 'left'; } $text = $parts[0]; } return $this->format_image($url, $text, $text, $align); } else { $url = $this->real_path($url); return parser_utils::h('a', $text, array('href' => $url, 'class' => 'wiki-attachment')); } } } parser/markups/creole.php000064400000014125152265517660011526 0ustar00 array( 'expression' => "/^\{\{\{(.*?)\}\}\}/ims", 'tags' => array(), 'token' => array('{{{', '}}}') ), 'header' => array( 'expression' => "/^\ *(={1,6})\ *(.+?)=*\ *$/ims", 'tags' => array(), //none 'token' => '=' ), 'table' => array( 'expression' => "/^(?:\|.*?\|\ *\n)+/ims" ), 'line_break' => array( 'expression' => "/^----\s*$/im", 'token' => '----', 'tags' => array() ), 'list' => array( 'expression' => "/((?:^\ *[\*#][^\*#]\ *.+?)(?:^\ *[\*#]{1,5}\ *.+?)*)(\n\s*(?:\n|<(?:h\d|pre|table|tbody|thead|tr|th|td|ul|li|ol|hr)))/ims", 'tags' => array(), 'token' => array('*', '#') ), 'paragraph' => array( 'expression' => "/^\ *((?:<(?!\ *\/?(?:h\d|pre|table|tbody|thead|tr|th|td|ul|li|ol|hr)\ *\/?>)|[^<\s]).+?)\n\s*\n/ims", //not specified -> all tags (null or unset) 'tag' => 'p' ) ); protected $tagrules = array( 'nowiki' => array( 'expression' => "/\{\{\{(.*?)\}\}\}/is", 'token' => array('{{{', '}}}') ), 'image' => array( 'expression' => "/\~?\{\{(.+)\|(.+)\}\}/i", 'tags' => array(), 'token' => array('{{', '|Alt}}') ), 'link' => array( 'expression' => "/\~?\[\[(.+?)\]\]/is", 'tag' => 'a', 'token' => array('[[', ']]') ), 'url' => array( 'expression' => "/\~?(? 'a', 'token' => "http://" ), 'line_break' => array( 'expression' => "/\\\\\\\\/", 'tag' => 'br', 'simple' => true, 'token' => '----' ), 'bold' => array( 'expression' => "/\*\*(.*?)(?:\*\*|$)/is", 'tag' => 'strong', 'token' => array('**', '**') ), 'italic' => array( 'expression' => "#(? 'em', 'token' => array('//', '//') ) ); /** * Block hooks */ protected function before_parsing() { $this->string = htmlspecialchars($this->string, ENT_COMPAT); parent::before_parsing(); } public function get_section($header, $text, $clean = false) { // The requested header is likely to have been passed to htmlspecialchars in // self::before_parsing(), therefore we should decode it when looking for it. return parent::get_section(htmlspecialchars_decode($header, ENT_COMPAT), $text, $clean); } protected function header_block_rule($match) { $num = strlen($match[1]); $text = trim($match[2]); $text = preg_replace("/\s*={1,$num}$/im", "", $text); return $this->generate_header($text, $num); } /** * Table generation */ protected function table_block_rule($match) { $rows = explode("\n", $match[0]); $table = array(); foreach($rows as $r) { if(empty($r)) { continue; } $rawcells = explode("|", $r); $cells = array(); array_shift($rawcells); array_pop($rawcells); foreach($rawcells as $c) { if(!empty($c)) { if($c[0] == "=") { $type = 'header'; $c = substr($c, 1); } else { $type = 'normal'; } $this->rules($c); $cells[] = array($type, $c); } } $table[] = $cells; } return $this->generate_table($table); } protected function paragraph_block_rule($match) { $text = $match[1]; foreach($this->tagrules as $tr) { if(isset($tr['token'])) { if(is_array($tr['token'])) { $this->escape_token_string($text, $tr['token'][0]); $this->escape_token_string($text, $tr['token'][1]); } else { $this->escape_token_string($text, $tr['token']); } } } $this->escape_token_string($text, "~"); return $text; } /** * Escape token when it is "negated" */ private function escape_token_string(&$text, $token) { $text = str_replace("~".$token, $this->protect($token), $text); } /** * Tag functions */ protected function url_tag_rule($match) { if(strpos($match[0], "~") === 0) { return substr($match[0], 1); } else { $text = trim($match[0]); $options = array('href' => $text); return array($text, $options); } } protected function link_tag_rule($match) { $text = trim($match[1]); if(strpos($match[0], "~") === 0) { return substr($match[0], 1); } else { return $this->format_link($text); } } /** * Special treatment of // ** // ** // */ protected function bold_tag_rule($match) { $text = $match[1]; $this->rules($text, array('only' => array('italic'))); if(strpos($text, "//") !== false) { $text = str_replace("//", $this->protect("//"), $text); } return array($text, array()); } protected function image_tag_rule($match) { if(strpos($match[0], "~") === 0) { return substr($match[0], 1); } return $this->format_image($match[1], $match[2]); } } parser/markups/html.php000064400000006777152265517660011237 0ustar00 and atto

) */ protected $minheaderlevel = null; public function __construct() { parent::__construct(); // The order is important, headers should be parsed before links. $this->tagrules = array( // Headers are considered tags here. 'header' => array( 'expression' => "/<\s*h([1-6])\s*>(.+?)<\/h[1-6]>/is" ), 'link' => $this->tagrules['link'], 'url' => $this->tagrules['url'] ); } /** * Find minimum header level used on the page (

,

, ...) * * @param string $text * @return int */ protected function find_min_header_level($text) { preg_match_all($this->tagrules['header']['expression'], $text, $matches); return !empty($matches[1]) ? min($matches[1]) : 1; } protected function before_parsing() { parent::before_parsing(); $this->minheaderlevel = $this->find_min_header_level($this->string); // Protect all explicit links from further wiki parsing. The link text may contain another URL which would get // converted into another link via {@see nwiki_parser::$tagrules} 'url' element. if (preg_match_all('/]+?>(.*?)<\/a>/is', $this->string, $matches)) { foreach (array_unique($matches[0]) as $match) { $this->string = str_replace($match, $this->protect($match), $this->string); } } $this->rules($this->string); } /** * Header tag rule * @param array $match Header regex match * @return string */ protected function header_tag_rule($match) { return $this->generate_header($match[2], (int)$match[1] - $this->minheaderlevel + 1); } /** * Section editing: Special for HTML Parser (It parses

) */ public function get_section($header, $text, $clean = false) { if ($clean) { $text = preg_replace('/\r\n/', "\n", $text); $text = preg_replace('/\r/', "\n", $text); $text .= "\n\n"; } $minheaderlevel = $this->find_min_header_level($text); $h1 = array("<\s*h{$minheaderlevel}\s*>", "<\/h{$minheaderlevel}>"); $regex = "/(.*?)({$h1[0]}\s*".preg_quote($header, '/')."\s*{$h1[1]}.*?)((?:{$h1[0]}.*)|$)/is"; preg_match($regex, $text, $match); if (!empty($match)) { return array($match[1], $match[2], $match[3]); } else { return false; } } protected function get_repeated_sections(&$text, $repeated = array()) { $this->repeated_sections = $repeated; return preg_replace_callback($this->tagrules['header'], array($this, 'get_repeated_sections_callback'), $text); } protected function get_repeated_sections_callback($match) { $text = trim($match[2]); if (in_array($text, $this->repeated_sections)) { $this->returnvalues['repeated_sections'][] = $text; return parser_utils::h('p', $text); } else { $this->repeated_sections[] = $text; } return $match[0]; } } parser/markups/wikimarkup.php000064400000032520152265517660012437 0ustar00 "Inside the link", 'url' => "http://url.com/Wiki/Entry", 'new' => false). */ private $linkgeneratorcallback = array('parser_utils', 'wiki_parser_link_callback'); private $linkgeneratorcallbackargs = array(); /** * Table generator callback */ private $tablegeneratorcallback = array('parser_utils', 'wiki_parser_table_callback'); /** * Get real path from relative path */ private $realpathcallback = array('parser_utils', 'wiki_parser_real_path'); private $realpathcallbackargs = array(); /** * Before and after parsing... */ protected function before_parsing() { $this->toc = array(); $this->string = preg_replace('/\r\n/', "\n", $this->string); $this->string = preg_replace('/\r/', "\n", $this->string); $this->string .= "\n\n"; if (!$this->printable && $this->section_editing) { $this->returnvalues['unparsed_text'] = $this->string; $this->string = $this->get_repeated_sections($this->string); } } protected function after_parsing() { if (!$this->printable) { $this->returnvalues['repeated_sections'] = array_unique($this->returnvalues['repeated_sections']); } $this->process_toc(); $this->string = preg_replace("/\n\s/", "\n", $this->string); $this->string = preg_replace("/\n{2,}/", "\n", $this->string); $this->string = trim($this->string); $this->string .= "\n"; } /** * Set options */ protected function set_options($options) { parent::set_options($options); $this->returnvalues['link_count'] = array(); $this->returnvalues['repeated_sections'] = array(); $this->returnvalues['toc'] = ""; foreach ($options as $name => $o) { switch ($name) { case 'link_callback': $callback = explode(':', $o); global $CFG; require_once($CFG->dirroot . $callback[0]); if (function_exists($callback[1])) { $this->linkgeneratorcallback = $callback[1]; } break; case 'link_callback_args': if (is_array($o)) { $this->linkgeneratorcallbackargs = $o; } break; case 'real_path_callback': $callback = explode(':', $o); global $CFG; require_once($CFG->dirroot . $callback[0]); if (function_exists($callback[1])) { $this->realpathcallback = $callback[1]; } break; case 'real_path_callback_args': if (is_array($o)) { $this->realpathcallbackargs = $o; } break; case 'table_callback': $callback = explode(':', $o); global $CFG; require_once($CFG->dirroot . $callback[0]); if (function_exists($callback[1])) { $this->tablegeneratorcallback = $callback[1]; } break; case 'pretty_print': if ($o) { $this->pretty_print = true; } break; case 'pageid': $this->wiki_page_id = $o; break; case 'printable': if ($o) { $this->printable = true; } break; } } } /** * Generic block rules */ protected function line_break_block_rule($match) { return '
'; } protected function list_block_rule($match) { preg_match_all("/^\ *([\*\#]{1,5})\ *((?:[^\n]|\n(?!(?:\ *[\*\#])|\n))+)/im", $match[1], $listitems, PREG_SET_ORDER); return $this->process_block_list($listitems) . $match[2]; } protected function nowiki_block_rule($match) { return parser_utils::h('pre', $this->protect($match[1])); } /** * Generic tag rules */ protected function nowiki_tag_rule($match) { return parser_utils::h('tt', $this->protect($match[1])); } /** * Header generation */ protected function generate_header($text, $level) { $toctext = $text = trim($text); if (!$this->pretty_print && $level == 1) { $editlink = '[' . get_string('editsection', 'wiki') . ']'; $url = array('href' => "edit.php?pageid={$this->wiki_page_id}§ion=" . urlencode($text), 'class' => 'wiki_edit_section'); $text .= ' ' . parser_utils::h('a', $this->protect($editlink), $url); $toctext .= ' ' . parser_utils::h('a', $editlink, $url); } if ($level <= $this->maxheaderdepth) { $this->toc[] = array($level, $toctext); $num = count($this->toc); $text = parser_utils::h('a', "", array('name' => "toc-$num")) . $text; } // Display headers as

and lower for accessibility. return parser_utils::h('h' . min(6, $level + 2), $text) . "\n\n"; } /** * Table of contents processing after parsing */ protected function process_toc() { if (empty($this->toc)) { return; } $toc = ""; $currentsection = array(0, 0, 0); $i = 1; foreach ($this->toc as & $header) { switch ($header[0]) { case 1: $currentsection = array($currentsection[0] + 1, 0, 0); break; case 2: $currentsection[1]++; $currentsection[2] = 0; if ($currentsection[0] == 0) { $currentsection[0]++; } break; case 3: $currentsection[2]++; if ($currentsection[1] == 0) { $currentsection[1]++; } if ($currentsection[0] == 0) { $currentsection[0]++; } break; default: continue 2; } $number = "$currentsection[0]"; if (!empty($currentsection[1])) { $number .= ".$currentsection[1]"; if (!empty($currentsection[2])) { $number .= ".$currentsection[2]"; } } $toc .= parser_utils::h('p', $number . ". " . parser_utils::h('a', str_replace(array('[[', ']]'), '', $header[1]), array('href' => "#toc-$i")), array('class' => 'wiki-toc-section-' . $header[0] . " wiki-toc-section")); $i++; } $this->returnvalues['toc'] = "

" . get_string('tableofcontents', 'wiki') . "

$toc
"; } /** * List helpers */ private function process_block_list($listitems) { $list = array(); foreach ($listitems as $li) { $text = str_replace("\n", "", $li[2]); $this->rules($text); if ($li[1][0] == '*') { $type = 'ul'; } else { $type = 'ol'; } $list[] = array(strlen($li[1]), $text, $type); } $type = $list[0][2]; return "<$type>" . "\n" . $this->generate_list($list) . "\n" . "" . "\n"; } /** * List generation function from an array of array(level, text) */ protected function generate_list($listitems) { $list = ""; $current_depth = 1; $next_depth = 1; $liststack = array(); for ($lc = 0; $lc < count($listitems) && $next_depth; $lc++) { $cli = $listitems[$lc]; $nli = isset($listitems[$lc + 1]) ? $listitems[$lc + 1] : null; $text = $cli[1]; $current_depth = $next_depth; $next_depth = $nli ? $nli[0] : null; if ($next_depth == $current_depth || $next_depth == null) { $list .= parser_utils::h('li', $text) . "\n"; } else if ($next_depth > $current_depth) { $next_depth = $current_depth + 1; $list .= "
  • " . $text . "\n"; $list .= "<" . $nli[2] . ">" . "\n"; $liststack[] = $nli[2]; } else { $list .= parser_utils::h('li', $text) . "\n"; for ($lv = $next_depth; $lv < $current_depth; $lv++) { $type = array_pop($liststack); $list .= "" . "\n" . "
  • " . "\n"; } } } for ($lv = 1; $lv < $current_depth; $lv++) { $type = array_pop($liststack); $list .= "" . "\n" . "" . "\n"; } return $list; } /** * Table generation functions */ protected function generate_table($table) { $table_html = call_user_func_array($this->tablegeneratorcallback, array($table)); return $table_html; } protected function format_image($src, $alt, $caption = "", $align = 'left') { $src = $this->real_path($src); return parser_utils::h('div', parser_utils::h('p', $caption) . '' . $alt . '', array('class' => 'wiki_image_' . $align)); } protected function real_path($url) { $callbackargs = array_merge(array($url), $this->realpathcallbackargs); return call_user_func_array($this->realpathcallback, array_values($callbackargs)); } /** * Link internal callback */ protected function link($link, $anchor = "") { $link = trim($link); if (preg_match("/^(https?|s?ftp):\/\/.+$/i", $link)) { $link = trim($link, ",.?!"); return array('content' => $link, 'url' => $link); } else { $callbackargs = $this->linkgeneratorcallbackargs; $callbackargs['anchor'] = $anchor; $link = call_user_func_array($this->linkgeneratorcallback, array($link, $callbackargs)); if (isset($link['link_info'])) { $l = $link['link_info']['link']; unset($link['link_info']['link']); $this->returnvalues['link_count'][$l] = $link['link_info']; } return $link; } } /** * Format links */ protected function format_link($text) { $matches = array(); if (preg_match("/^([^\|]+)\|(.+)$/i", $text, $matches)) { $link = $matches[1]; $content = trim($matches[2]); if (preg_match("/(.+)#(.*)/is", $link, $matches)) { $link = $this->link($matches[1], $matches[2]); } else if ($link[0] == '#') { $link = array('url' => "#" . urlencode(substr($link, 1))); } else { $link = $this->link($link); } $link['content'] = $content; } else { $link = $this->link($text); } if (isset($link['new']) && $link['new']) { $options = array('class' => 'wiki_newentry'); } else { $options = array(); } $link['content'] = $this->protect($link['content']); $link['url'] = $this->protect($link['url']); $options['href'] = $link['url']; if ($this->printable) { $options['href'] = '#'; //no target for the link } return array($link['content'], $options); } /** * Section editing */ public function get_section($header, $text, $clean = false) { if ($clean) { $text = preg_replace('/\r\n/', "\n", $text); $text = preg_replace('/\r/', "\n", $text); $text .= "\n\n"; } $regex = "/(.*?)(=\ *".preg_quote($header, '/')."\ *=*\n.*?)((?:\n=[^=]+.*)|$)/is"; preg_match($regex, $text, $match); if (!empty($match)) { return array($match[1], $match[2], $match[3]); } else { return false; } } protected function get_repeated_sections(&$text, $repeated = array()) { $this->repeated_sections = $repeated; return preg_replace_callback($this->blockrules['header']['expression'], array($this, 'get_repeated_sections_callback'), $text); } protected function get_repeated_sections_callback($match) { $num = strlen($match[1]); $text = trim($match[2]); if ($num == 1) { if (in_array($text, $this->repeated_sections)) { $this->returnvalues['repeated_sections'][] = $text; return $text . "\n"; } else { $this->repeated_sections[] = $text; } } return $match[0]; } } parser/parser.php000064400000022452152265517660010071 0ustar00. /** * Library of functions and constants for module wiki * * It contains the great majority of functions defined by Moodle * that are mandatory to develop a module. * * @package mod_wiki * @copyright 2009 Marc Alier, Jordi Piguillem marc.alier@upc.edu * @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu * * @author Jordi Piguillem * @author Marc Alier * @author David Jimenez * @author Josep Arus * @author Kenneth Riba * * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); /** * Generic parser implementation * * @author Josep Arús * * @license http://www.gnu.org/copyleft/gpl.html GNU Public License * @package mod_wiki */ class wiki_parser_proxy { /** * @var array $parsers Array of parser instances */ private static $parsers = []; /** * Parse a string using a specific parser * * @param string $string The string to parse * @param string $type The parser type * @param array $options The parser options * @return mixed The parsed string or false if the parser type is not found */ public static function parse(&$string, $type, $options = []) { $type = strtolower($type); self::$parsers[$type] = null; // Reset the current parser because it may have other options. if (self::create_parser_instance($type)) { return self::$parsers[$type]->parse($string, $options); } else { return false; } } public static function get_token($name, $type) { if (self::create_parser_instance($type)) { return self::$parsers[$type]->get_token($name); } else { return false; } } public static function get_section(&$string, $type, $section, $allcontent = false) { if (self::create_parser_instance($type)) { $content = self::$parsers[$type]->get_section($section, $string, true); if ($allcontent) { return $content; } else { return is_array($content) ? $content[1] : null; } } else { return false; } } private static function create_parser_instance($type) { global $CFG; $type = clean_param($type, PARAM_ALPHA); if (empty(self::$parsers[$type])) { $path = "$CFG->dirroot/mod/wiki/parser/markups/$type.php"; if (!file_exists($path)) { throw new moodle_exception("Parser type $type not found"); } include_once($path); $class = strtolower($type) . "_parser"; if (class_exists($class)) { self::$parsers[$type] = new $class; return true; } else { return false; } } else { return true; } } } require_once('utils.php'); abstract class generic_parser { protected $string; protected $blockrules = array(); protected $tagrules = array(); private $rulestack = array(); protected $parserstatus = 'Before'; /** * Dynamic return values */ protected $returnvalues = array(); private $nowikiindex = array(); protected $nowikitoken = "%!"; public function __construct() { } /** * Parse function */ public function parse(&$string, $options = array()) { if (!is_string($string)) { return false; } $this->string =& $string; $this->set_options(is_array($options) ? $options : array()); $this->initialize_nowiki_index(); if (method_exists($this, 'before_parsing')) { $this->before_parsing(); } $this->parserstatus = 'Parsing'; foreach ($this->blockrules as $name => $block) { $this->process_block_rule($name, $block); } $this->commit_nowiki_index(); $this->parserstatus = 'After'; if (method_exists($this, 'after_parsing')) { $this->after_parsing(); } return array('parsed_text' => $this->string) + $this->returnvalues; } /** * Initialize options */ protected function set_options($options) { } /** * Block processing function & callbacks */ protected function process_block_rule($name, $block) { $this->rulestack[] = array('callback' => method_exists($this, $name . "_block_rule") ? $name . "_block_rule" : null, 'rule' => $block); $this->string = preg_replace_callback($block['expression'], array($this, 'block_callback'), $this->string); array_pop($this->rulestack); } private function block_callback($match) { $rule = end($this->rulestack); if (!empty($rule['callback'])) { $stuff = $this->{$rule['callback']}($match); } else { $stuff = $match[1]; } if (is_array($stuff) && $rule['rule']['tag']) { $this->rules($stuff[0], $rule['rule']['tags']); $stuff = "\n" . parser_utils::h($rule['rule']['tag'], $stuff[0], $stuff[1]) . "\n"; } else { if (!isset($rule['rule']['tags'])) { $rule['rule']['tags'] = null; } $this->rules($stuff, $rule['rule']['tags']); if (isset($rule['rule']['tag']) && is_string($rule['rule']['tag'])) { $stuff = "\n" . parser_utils::h($rule['rule']['tag'], $stuff) . "\n"; } } return $stuff; } /** * Rules processing function & callback */ final protected function rules(&$text, $rules = null) { if ($rules === null) { $rules = array('except' => array()); } else if (is_array($rules) && count($rules) > 1) { $rules = array('only' => $rules); } if (isset($rules['only']) && is_array($rules['only'])) { $rules = $rules['only']; foreach ($rules as $r) { if (!empty($this->tagrules[$r])) { $this->process_tag_rule($r, $this->tagrules[$r], $text); } } } else if (isset($rules['except']) && is_array($rules['except'])) { $rules = $rules['except']; foreach ($this->tagrules as $r => $tr) { if (!in_array($r, $rules)) { $this->process_tag_rule($r, $tr, $text); } } } } private function process_tag_rule($name, $rule, &$text) { if (method_exists($this, $name . "_tag_rule")) { $this->rulestack[] = array('callback' => $name . "_tag_rule", 'rule' => $rule); $text = preg_replace_callback($rule['expression'], array($this, 'tag_callback'), $text); array_pop($this->rulestack); } else { if (isset($rule['simple'])) { $replace = "<{$rule['tag']} />"; } else { $replace = parser_utils::h($rule['tag'], "$1"); } $text = preg_replace($rule['expression'], $replace, $text); } } private function tag_callback($match) { $rule = end($this->rulestack); $stuff = $this->{$rule['callback']}($match); if (is_array($stuff)) { return parser_utils::h($rule['rule']['tag'], $stuff[0], $stuff[1]); } else { return $stuff; } } /** * Special nowiki parser index */ private function initialize_nowiki_index() { $token = "\Q" . $this->nowikitoken . "\E"; $this->string = preg_replace_callback("/" . $token . "\d+" . $token . "/", array($this, "initialize_nowiki_index_callback"), $this->string); } private function initialize_nowiki_index_callback($match) { return $this->protect($match[0]); } protected function protect($text) { $this->nowikiindex[] = $text; return $this->nowikitoken . (count($this->nowikiindex) - 1) . $this->nowikitoken; } private function commit_nowiki_index() { $token = "\Q" . $this->nowikitoken . "\E"; $this->string = preg_replace_callback("/" . $token . "(\d+)" . $token . "/", array($this, "commit_nowiki_index_callback"), $this->string); } private function commit_nowiki_index_callback($match) { return $this->nowikiindex[intval($match[1])]; } /** * Get token of the parsable element $name. */ public function get_token($name) { foreach (array_merge($this->blockrules, $this->tagrules) as $n => $v) { if ($name == $n && isset($v['token'])) { return $v['token'] ? $v['token'] : false; } } return false; } } backup/moodle2/restore_wiki_activity_task.class.php000064400000011531152265517660016653 0ustar00. /** * @package mod_wiki * @subpackage backup-moodle2 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); require_once($CFG->dirroot . '/mod/wiki/backup/moodle2/restore_wiki_stepslib.php'); // Because it exists (must) /** * wiki restore task that provides all the settings and steps to perform one * complete restore of the activity */ class restore_wiki_activity_task extends restore_activity_task { /** * Define (add) particular settings this activity can have */ protected function define_my_settings() { // No particular settings for this activity } /** * Define (add) particular steps this activity can have */ protected function define_my_steps() { // wiki only has one structure step $this->add_step(new restore_wiki_activity_structure_step('wiki_structure', 'wiki.xml')); } /** * Define the contents in the activity that must be * processed by the link decoder */ public static function define_decode_contents() { $contents = array(); $contents[] = new restore_decode_content('wiki', array('intro'), 'wiki'); $contents[] = new restore_decode_content('wiki_versions', array('content'), 'wiki_version'); $contents[] = new restore_decode_content('wiki_pages', array('cachedcontent'), 'wiki_page'); return $contents; } /** * Define the decoding rules for links belonging * to the activity to be executed by the link decoder */ public static function define_decode_rules() { $rules = array(); $rules[] = new restore_decode_rule('WIKIINDEX', '/mod/wiki/index.php?id=$1', 'course'); $rules[] = new restore_decode_rule('WIKIVIEWBYID', '/mod/wiki/view.php?id=$1', 'course_module'); $rules[] = new restore_decode_rule('WIKIPAGEBYID', '/mod/wiki/view.php?pageid=$1', 'wiki_page'); return $rules; } /** * Define the restore log rules that will be applied * by the {@link restore_logs_processor} when restoring * wiki logs. It must return one array * of {@link restore_log_rule} objects */ public static function define_restore_log_rules() { $rules = array(); $rules[] = new restore_log_rule('wiki', 'add', 'view.php?id={course_module}', '{wiki}'); $rules[] = new restore_log_rule('wiki', 'update', 'view.php?id={course_module}', '{wiki}'); $rules[] = new restore_log_rule('wiki', 'view', 'view.php?id={course_module}', '{wiki}'); $rules[] = new restore_log_rule('wiki', 'comments', 'comments.php?id={course_module}', '{wiki}'); $rules[] = new restore_log_rule('wiki', 'diff', 'diff.php?id={course_module}', '{wiki}'); $rules[] = new restore_log_rule('wiki', 'edit', 'edit.php?id={course_module}', '{wiki}'); $rules[] = new restore_log_rule('wiki', 'history', 'history.php?id={course_module}', '{wiki}'); $rules[] = new restore_log_rule('wiki', 'map', 'map.php?id={course_module}', '{wiki}'); $rules[] = new restore_log_rule('wiki', 'overridelocks', 'overridelocks.php?id={course_module}', '{wiki}'); /// TODO: Examine these 2 rules, because module is not "wiki", and it shouldn't happen $rules[] = new restore_log_rule('restore', 'restore', 'view.php?id={course_module}', '{wiki}'); $rules[] = new restore_log_rule('createpage', 'createpage', 'view.php?id={course_module}', '{wiki}'); return $rules; } /** * Define the restore log rules that will be applied * by the {@link restore_logs_processor} when restoring * course logs. It must return one array * of {@link restore_log_rule} objects * * Note this rules are applied when restoring course logs * by the restore final task, but are defined here at * activity level. All them are rules not linked to any module instance (cmid = 0) */ public static function define_restore_log_rules_for_course() { $rules = array(); $rules[] = new restore_log_rule('wiki', 'view all', 'index.php?id={course}', null); return $rules; } } backup/moodle2/backup_wiki_activity_task.class.php000064400000005077152265517660016445 0ustar00. /** * Defines backup_wiki_activity_task class * * @package mod_wiki * @category backup * @copyright 2010 Jordi Piguillem * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); require_once($CFG->dirroot . '/mod/wiki/backup/moodle2/backup_wiki_stepslib.php'); require_once($CFG->dirroot . '/mod/wiki/backup/moodle2/backup_wiki_settingslib.php'); /** * Provides all the settings and steps to perform one complete backup of the activity */ class backup_wiki_activity_task extends backup_activity_task { /** * No specific settings for this activity */ protected function define_my_settings() { } /** * Defines a backup step to store the instance data in the wiki.xml file */ protected function define_my_steps() { $this->add_step(new backup_wiki_activity_structure_step('wiki_structure', 'wiki.xml')); } /** * Encodes URLs to the index.php and view.php scripts * * @param string $content some HTML text that eventually contains URLs to the activity instance scripts * @return string the content with the URLs encoded */ public static function encode_content_links($content) { global $CFG; $base = preg_quote($CFG->wwwroot, "/"); // Link to the list of wikis $search = "/(" . $base . "\/mod\/wiki\/index.php\?id\=)([0-9]+)/"; $content = preg_replace($search, '$@WIKIINDEX*$2@$', $content); // Link to wiki view by moduleid $search = "/(" . $base . "\/mod\/wiki\/view.php\?id\=)([0-9]+)/"; $content = preg_replace($search, '$@WIKIVIEWBYID*$2@$', $content); // Link to wiki view by pageid $search = "/(" . $base . "\/mod\/wiki\/view.php\?pageid\=)([0-9]+)/"; $content = preg_replace($search, '$@WIKIPAGEBYID*$2@$', $content); return $content; } } backup/moodle2/restore_wiki_stepslib.php000064400000015316152265517660014523 0ustar00. /** * @package mod_wiki * @subpackage backup-moodle2 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ /** * Define all the restore steps that will be used by the restore_wiki_activity_task */ /** * Structure step to restore one wiki activity */ class restore_wiki_activity_structure_step extends restore_activity_structure_step { protected function define_structure() { $paths = array(); $userinfo = $this->get_setting_value('userinfo'); $paths[] = new restore_path_element('wiki', '/activity/wiki'); if ($userinfo) { $paths[] = new restore_path_element('wiki_subwiki', '/activity/wiki/subwikis/subwiki'); $paths[] = new restore_path_element('wiki_page', '/activity/wiki/subwikis/subwiki/pages/page'); $paths[] = new restore_path_element('wiki_version', '/activity/wiki/subwikis/subwiki/pages/page/versions/version'); $paths[] = new restore_path_element('wiki_tag', '/activity/wiki/subwikis/subwiki/pages/page/tags/tag'); $paths[] = new restore_path_element('wiki_synonym', '/activity/wiki/subwikis/subwiki/synonyms/synonym'); $paths[] = new restore_path_element('wiki_link', '/activity/wiki/subwikis/subwiki/links/link'); } // Return the paths wrapped into standard activity structure return $this->prepare_activity_structure($paths); } protected function process_wiki($data) { global $DB; $data = (object)$data; $oldid = $data->id; $data->course = $this->get_courseid(); // Any changes to the list of dates that needs to be rolled should be same during course restore and course reset. // See MDL-9367. $data->editbegin = $this->apply_date_offset($data->editbegin); $data->editend = $this->apply_date_offset($data->editend); $data->defaultformat = clean_param($data->defaultformat, PARAM_ALPHA); // insert the wiki record $newitemid = $DB->insert_record('wiki', $data); // immediately after inserting "activity" record, call this $this->apply_activity_instance($newitemid); } protected function process_wiki_subwiki($data) { global $DB; $data = (object) $data; $oldid = $data->id; $data->wikiid = $this->get_new_parentid('wiki'); // If the groupid is not equal to zero, get the mapping for the group. if ((int) $data->groupid !== 0) { $data->groupid = $this->get_mappingid('group', $data->groupid); } // If the userid is not equal to zero, get the mapping for the user. if ((int) $data->userid !== 0) { $data->userid = $this->get_mappingid('user', $data->userid); } // If these values are not equal to false then a mapping was successfully made. if ($data->groupid !== false && $data->userid !== false) { $newitemid = $DB->insert_record('wiki_subwikis', $data); } else { $newitemid = false; } $this->set_mapping('wiki_subwiki', $oldid, $newitemid, true); } protected function process_wiki_page($data) { global $DB; $data = (object) $data; $oldid = $data->id; $data->subwikiid = $this->get_new_parentid('wiki_subwiki'); $data->userid = $this->get_mappingid('user', $data->userid); // Check that we were able to get a parentid for this page. if ($data->subwikiid !== false) { $newitemid = $DB->insert_record('wiki_pages', $data); } else { $newitemid = false; } $this->set_mapping('wiki_page', $oldid, $newitemid, true); } protected function process_wiki_version($data) { global $DB; $data = (object)$data; $oldid = $data->id; $data->pageid = $this->get_new_parentid('wiki_page'); $data->userid = $this->get_mappingid('user', $data->userid); $data->contentformat = clean_param($data->contentformat, PARAM_ALPHA); $newitemid = $DB->insert_record('wiki_versions', $data); $this->set_mapping('wiki_version', $oldid, $newitemid); } protected function process_wiki_synonym($data) { global $DB; $data = (object)$data; $oldid = $data->id; $data->subwikiid = $this->get_new_parentid('wiki_subwiki'); $data->pageid = $this->get_mappingid('wiki_page', $data->pageid); $newitemid = $DB->insert_record('wiki_synonyms', $data); // No need to save this mapping as far as nothing depend on it // (child paths, file areas nor links decoder) } protected function process_wiki_link($data) { global $DB; $data = (object)$data; $oldid = $data->id; $data->subwikiid = $this->get_new_parentid('wiki_subwiki'); $data->frompageid = $this->get_mappingid('wiki_page', $data->frompageid); $data->topageid = $this->get_mappingid('wiki_page', $data->topageid); $newitemid = $DB->insert_record('wiki_links', $data); // No need to save this mapping as far as nothing depend on it // (child paths, file areas nor links decoder) } protected function process_wiki_tag($data) { global $CFG, $DB; $data = (object)$data; $oldid = $data->id; if (!core_tag_tag::is_enabled('mod_wiki', 'wiki_pages')) { // Tags disabled in server, nothing to process. return; } $tag = $data->rawname; $itemid = $this->get_new_parentid('wiki_page'); $wikiid = $this->get_new_parentid('wiki'); $context = context_module::instance($this->task->get_moduleid()); core_tag_tag::add_item_tag('mod_wiki', 'wiki_pages', $itemid, $context, $tag); } protected function after_execute() { // Add wiki related files, no need to match by itemname (just internally handled context) $this->add_related_files('mod_wiki', 'intro', null); $this->add_related_files('mod_wiki', 'attachments', 'wiki_subwiki'); } } backup/moodle2/backup_wiki_stepslib.php000064400000011777152265517660014314 0ustar00. /** * @package mod_wiki * @subpackage backup-moodle2 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ /** * Define all the backup steps that will be used by the backup_wiki_activity_task */ /** * Define the complete wiki structure for backup, with file and id annotations */ class backup_wiki_activity_structure_step extends backup_activity_structure_step { protected function define_structure() { // To know if we are including userinfo $userinfo = $this->get_setting_value('userinfo'); // Define each element separated $wiki = new backup_nested_element('wiki', array('id'), array('name', 'intro', 'introformat', 'timecreated', 'timemodified', 'firstpagetitle', 'wikimode', 'defaultformat', 'forceformat', 'editbegin', 'editend')); $subwikis = new backup_nested_element('subwikis'); $subwiki = new backup_nested_element('subwiki', array('id'), array('groupid', 'userid')); $pages = new backup_nested_element('pages'); $page = new backup_nested_element('page', array('id'), array('title', 'cachedcontent', 'timecreated', 'timemodified', 'timerendered', 'userid', 'pageviews', 'readonly')); $synonyms = new backup_nested_element('synonyms'); $synonym = new backup_nested_element('synonym', array('id'), array('pageid', 'pagesynonym')); $links = new backup_nested_element('links'); $link = new backup_nested_element('link', array('id'), array('frompageid', 'topageid', 'tomissingpage')); $versions = new backup_nested_element('versions'); $version = new backup_nested_element('version', array('id'), array('content', 'contentformat', 'version', 'timecreated', 'userid')); $tags = new backup_nested_element('tags'); $tag = new backup_nested_element('tag', array('id'), array('name', 'rawname')); // Build the tree $wiki->add_child($subwikis); $subwikis->add_child($subwiki); $subwiki->add_child($pages); $pages->add_child($page); $subwiki->add_child($synonyms); $synonyms->add_child($synonym); $subwiki->add_child($links); $links->add_child($link); $page->add_child($versions); $versions->add_child($version); $page->add_child($tags); $tags->add_child($tag); // Define sources $wiki->set_source_table('wiki', array('id' => backup::VAR_ACTIVITYID)); // All these source definitions only happen if we are including user info if ($userinfo) { $subwiki->set_source_sql(' SELECT * FROM {wiki_subwikis} WHERE wikiid = ?', array(backup::VAR_PARENTID)); $page->set_source_table('wiki_pages', array('subwikiid' => backup::VAR_PARENTID)); $synonym->set_source_table('wiki_synonyms', array('subwikiid' => backup::VAR_PARENTID)); $link->set_source_table('wiki_links', array('subwikiid' => backup::VAR_PARENTID)); $version->set_source_table('wiki_versions', array('pageid' => backup::VAR_PARENTID)); $tag->set_source_sql('SELECT t.id, t.name, t.rawname FROM {tag} t JOIN {tag_instance} ti ON ti.tagid = t.id WHERE ti.itemtype = ? AND ti.component = ? AND ti.itemid = ?', array( backup_helper::is_sqlparam('wiki_pages'), backup_helper::is_sqlparam('mod_wiki'), backup::VAR_PARENTID)); } // Define id annotations $subwiki->annotate_ids('group', 'groupid'); $subwiki->annotate_ids('user', 'userid'); $page->annotate_ids('user', 'userid'); $version->annotate_ids('user', 'userid'); // Define file annotations $wiki->annotate_files('mod_wiki', 'intro', null); // This file area hasn't itemid $subwiki->annotate_files('mod_wiki', 'attachments', 'id'); // This file area hasn't itemid // Return the root element (wiki), wrapped into standard activity structure return $this->prepare_activity_structure($wiki); } } backup/moodle2/backup_wiki_settingslib.php000064400000002165152265517660015005 0ustar00. /** * @package mod_wiki * @subpackage backup-moodle2 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ // This activity has not particular settings but the inherited from the generic // backup_activity_task so here there isn't any class definition, like the ones // existing in /backup/moodle2/backup_settingslib.php (activities section) backup/moodle1/lib.php000064400000030141152265517660010646 0ustar00. /** * Provides support for the conversion of moodle1 backup to the moodle2 format * Based off of a template @ http://docs.moodle.org/dev/Backup_1.9_conversion_for_developers * * @package mod_wiki * @copyright 2011 Aparup Banerjee * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); /** * Wiki conversion handler */ class moodle1_mod_wiki_handler extends moodle1_mod_handler { /** @var string initial content for creating first page from the optional 1.9 wiki file */ protected $initialcontent; /** @var string */ protected $initialcontentfilename; /** @var bool initial content page already exists */ protected $needinitpage = false; /** @var array a data element transfer buffer, can be used for transfer of data between xml path levels. */ protected $databuf = array(); /** @var moodle1_file_manager */ protected $fileman = null; /** @var int cmid */ protected $moduleid = null; /** * Declare the paths in moodle.xml we are able to convert * * The method returns list of {@link convert_path} instances. * For each path returned, the corresponding conversion method must be * defined. * * Note that the path /MOODLE_BACKUP/COURSE/MODULES/MOD/WIKI does not * actually exist in the file. The last element with the module name was * appended by the moodle1_converter class. * * @return array of {@link convert_path} instances */ public function get_paths() { return array( new convert_path( 'wiki', '/MOODLE_BACKUP/COURSE/MODULES/MOD/WIKI', array( 'newfields' => array( 'introformat' => '0', 'defaultformat' => 'html', //1.9 migrations default to html 'forceformat' => '1', 'editbegin' => '0', 'editend' => '0', 'timecreated' => time(), //2.x time of creation since theres no 1.9 time of creation ), 'renamefields' => array( 'summary' => 'intro', 'format' => 'introformat', 'firstpagetitle' => 'pagename', 'wtype' => 'wikimode' ), 'dropfields' => array( 'pagename', 'scaleid', 'ewikiprinttitle', 'htmlmode', 'ewikiacceptbinary', 'disablecamelcase', 'setpageflags', 'strippages', 'removepages', 'revertchanges' ) ) ), new convert_path( 'wiki_entries', '/MOODLE_BACKUP/COURSE/MODULES/MOD/WIKI/ENTRIES', array( 'newfields' => array( 'synonyms' => '0', 'links' => 'collaborative', ), 'dropfields' => array( 'pagename' ,'timemodified' ) ) ), new convert_path( 'wiki_entry', '/MOODLE_BACKUP/COURSE/MODULES/MOD/WIKI/ENTRIES/ENTRY' ), new convert_path( 'wiki_pages', '/MOODLE_BACKUP/COURSE/MODULES/MOD/WIKI/ENTRIES/ENTRY/PAGES' ), new convert_path( 'wiki_entry_page', '/MOODLE_BACKUP/COURSE/MODULES/MOD/WIKI/ENTRIES/ENTRY/PAGES/PAGE', array( 'newfields' => array( 'cachedcontent' => '**reparse needed**', 'timerendered' => '0', 'readonly' => '0', 'tags' => '' ), 'renamefields' => array( 'pagename' => 'title', 'created' => 'timecreated', 'lastmodified' => 'timemodified', 'hits' => 'pageviews' ), 'dropfields' => array( 'version', 'flags', 'author', 'refs', //refs will be reparsed during rendering 'meta' ) ) ) ); } /** * This is executed every time we have one /MOODLE_BACKUP/COURSE/MODULES/MOD/WIKI * data available */ public function process_wiki($data) { global $CFG; // We need to check a config setting. if (!empty($data['initialcontent'])) { //convert file in filename into a subwiki page if no entry created. $temppath = $this->converter->get_tempdir_path(); $filename = clean_param($data['initialcontent'], PARAM_FILE); $this->initialcontent = file_get_contents($temppath . '/course_files/' . $filename); $this->initialcontentfilename = $filename; $this->needinitpage = true; } unset($data['initialcontent']); if ($data['wikimode'] !== 'group') { $data['wikimode'] = 'individual'; //@todo need to create extra subwikis due to individual wikimode? //this would then need to reference the users in the course that is being restored.(some parent class API needed) } else { $data['wikimode'] = 'collaborative'; } if (empty($data['name'])) { $data['name'] = 'Wiki'; } // get the course module id and context id $instanceid = $data['id']; $cminfo = $this->get_cminfo($instanceid); $this->moduleid = $cminfo['id']; $contextid = $this->converter->get_contextid(CONTEXT_MODULE, $this->moduleid); // get a fresh new file manager for this instance $this->fileman = $this->converter->get_file_manager($contextid, 'mod_wiki'); // convert course files embedded into the intro $this->fileman->filearea = 'intro'; $this->fileman->itemid = 0; $data['intro'] = moodle1_converter::migrate_referenced_files($data['intro'], $this->fileman); // convert the introformat if necessary if ($CFG->texteditors !== 'textarea') { $data['intro'] = text_to_html($data['intro'], false, false, true); $data['introformat'] = FORMAT_HTML; } // we now have all information needed to start writing into the file $this->open_xml_writer("activities/wiki_{$this->moduleid}/wiki.xml"); $this->xmlwriter->begin_tag('activity', array('id' => $instanceid, 'moduleid' => $this->moduleid, 'modulename' => 'wiki', 'contextid' => $contextid)); $this->xmlwriter->begin_tag('wiki', array('id' => $instanceid)); foreach ($data as $field => $value) { if ($field <> 'id') { $this->xmlwriter->full_tag($field, $value); } } return $data; } public function on_wiki_entries_start() { $this->xmlwriter->begin_tag('subwikis'); $this->needinitpage = false; //backup has entries, so the initial_content file has been stored as a page in 1.9. } public function on_wiki_entries_end() { $this->xmlwriter->end_tag('subwikis'); } public function process_wiki_entry($data) { $this->xmlwriter->begin_tag('subwiki', array('id' => $data['id'])); unset($data['id']); unset($data['pagename']); unset($data['timemodified']); foreach ($data as $field => $value) { $this->xmlwriter->full_tag($field, $value); } } public function on_wiki_entry_end() { $this->xmlwriter->end_tag('subwiki'); } public function on_wiki_pages_start() { $this->xmlwriter->begin_tag('pages'); } public function on_wiki_pages_end() { $this->xmlwriter->end_tag('pages'); } public function process_wiki_entry_page($data) { // assimilate data to create later in extra virtual path page/versions/version/ $this->databuf['id'] = $this->converter->get_nextid(); $this->databuf['content'] = $data['content']; unset($data['content']); $this->databuf['contentformat'] = 'html'; $this->databuf['version'] = 0; $this->databuf['timecreated'] = $data['timecreated']; //do not unset, is reused $this->databuf['userid'] = $data['userid']; //do not unset, is reused // process page data (user data and also the one that is from $this->xmlwriter->begin_tag('page', array('id' => $data['id'])); unset($data['id']); // we already write it as attribute, do not repeat it as child element foreach ($data as $field => $value) { $this->xmlwriter->full_tag($field, $value); } // process page content as a version. $this->xmlwriter->begin_tag('versions'); $this->write_xml('version', $this->databuf, array('/version/id')); //version id from get_nextid() $this->xmlwriter->end_tag('versions'); } public function on_wiki_entry_page_end() { $this->xmlwriter->end_tag('page'); } /** * This is executed when we reach the closing tag of our 'wiki' path */ public function on_wiki_end() { global $USER; //check if the initial content needs to be created (and if a page is already there for it) if ($this->initialcontentfilename && $this->needinitpage) { //contruct (synthetic - not for cooking) a full path for creating entries/entry/pages/page $data_entry = array( 'id' => $this->converter->get_nextid(), //creating the first entry 'groupid' => 0, 'userid' => 0, 'synonyms' => '', 'links' => '' ); $data_page = array( 'id' => $this->converter->get_nextid(), //just creating the first page in the wiki 'title' => $this->initialcontentfilename, 'content' => $this->initialcontent, 'userid' => $USER->id, 'timecreated' => time(), 'timemodified' => 0, 'pageviews' => 0, 'cachedcontent' => '**reparse needed**', 'timerendered' => 0, 'readonly' => 0, 'tags' => '' ); //create xml with constructed page data (from initial_content file). $this->on_wiki_entries_start(); $this->process_wiki_entry($data_entry); $this->on_wiki_pages_start(); $this->process_wiki_entry_page($data_page); $this->on_wiki_entry_page_end(); $this->on_wiki_pages_end(); $this->on_wiki_entry_end(); $this->on_wiki_entries_end(); } //close wiki.xml $this->xmlwriter->end_tag('wiki'); $this->xmlwriter->end_tag('activity'); $this->close_xml_writer(); // write inforef.xml $this->open_xml_writer("activities/wiki_{$this->moduleid}/inforef.xml"); $this->xmlwriter->begin_tag('inforef'); $this->xmlwriter->begin_tag('fileref'); foreach ($this->fileman->get_fileids() as $fileid) { $this->write_xml('file', array('id' => $fileid)); } $this->xmlwriter->end_tag('fileref'); $this->xmlwriter->end_tag('inforef'); $this->close_xml_writer(); } } view.php000064400000024230152265517660006247 0ustar00. /** * This file contains all necessary code to view a wiki page * * @package mod_wiki * @copyright 2009 Marc Alier, Jordi Piguillem marc.alier@upc.edu * @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu * * @author Jordi Piguillem * @author Marc Alier * @author David Jimenez * @author Josep Arus * @author Kenneth Riba * * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once('../../config.php'); require_once($CFG->dirroot . '/mod/wiki/lib.php'); require_once($CFG->dirroot . '/mod/wiki/locallib.php'); require_once($CFG->dirroot . '/mod/wiki/pagelib.php'); $id = optional_param('id', 0, PARAM_INT); // Course Module ID $pageid = optional_param('pageid', 0, PARAM_INT); // Page ID $wid = optional_param('wid', 0, PARAM_INT); // Wiki ID $title = optional_param('title', '', PARAM_TEXT); // Page Title $currentgroup = optional_param('group', 0, PARAM_INT); // Group ID $userid = optional_param('uid', 0, PARAM_INT); // User ID $groupanduser = optional_param('groupanduser', 0, PARAM_TEXT); $edit = optional_param('edit', -1, PARAM_BOOL); $action = optional_param('action', '', PARAM_ALPHA); $swid = optional_param('swid', 0, PARAM_INT); // Subwiki ID $PAGE->force_settings_menu(); $PAGE->add_body_class('limitedwidth'); /* * Case 0: * * User that comes from a course. First wiki page must be shown * * URL params: id -> course module id * */ if ($id) { // Cheacking course module instance if (!$cm = get_coursemodule_from_id('wiki', $id)) { throw new \moodle_exception('invalidcoursemodule'); } // Checking course instance $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); require_course_login($course, true, $cm); // Checking wiki instance if (!$wiki = wiki_get_wiki($cm->instance)) { throw new \moodle_exception('incorrectwikiid', 'wiki'); } $PAGE->set_cm($cm); // Getting the subwiki corresponding to that wiki, group and user. // // Also setting the page if it exists or getting the first page title form // that wiki // Getting current group id $currentgroup = groups_get_activity_group($cm); // Getting current user id if ($wiki->wikimode == 'individual') { $userid = $USER->id; } else { $userid = 0; } // Getting subwiki. If it does not exists, redirecting to create page if (!$subwiki = wiki_get_subwiki_by_group($wiki->id, $currentgroup, $userid)) { $params = array('wid' => $wiki->id, 'group' => $currentgroup, 'uid' => $userid, 'title' => $wiki->firstpagetitle); $url = new moodle_url('/mod/wiki/create.php', $params); redirect($url); } // Getting first page. If it does not exists, redirecting to create page if (!$page = wiki_get_first_page($subwiki->id, $wiki)) { $params = array('swid'=>$subwiki->id, 'title'=>$wiki->firstpagetitle); $url = new moodle_url('/mod/wiki/create.php', $params); redirect($url); } /* * Case 1: * * A user wants to see a page. * * URL Params: pageid -> page id * */ } elseif ($pageid) { // Checking page instance if (!$page = wiki_get_page($pageid)) { throw new \moodle_exception('incorrectpageid', 'wiki'); } // Checking subwiki if (!$subwiki = wiki_get_subwiki($page->subwikiid)) { throw new \moodle_exception('incorrectsubwikiid', 'wiki'); } // Checking wiki instance of that subwiki if (!$wiki = wiki_get_wiki($subwiki->wikiid)) { throw new \moodle_exception('incorrectwikiid', 'wiki'); } // Checking course module instance if (!$cm = get_coursemodule_from_instance("wiki", $subwiki->wikiid)) { throw new \moodle_exception('invalidcoursemodule'); } $currentgroup = $subwiki->groupid; // Checking course instance $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); require_course_login($course, true, $cm); /* * Case 2: * * Trying to read a page from another group or user * * Page can exists or not. * * If it exists, page must be shown * * If it does not exists, system must ask for its creation * * URL params: wid -> subwiki id (required) * title -> a page title (required) * group -> group id (optional) * uid -> user id (optional) * groupanduser -> (optional) */ } elseif ($wid && $title) { // Setting wiki instance if (!$wiki = wiki_get_wiki($wid)) { throw new \moodle_exception('incorrectwikiid', 'wiki'); } // Checking course module if (!$cm = get_coursemodule_from_instance("wiki", $wiki->id)) { throw new \moodle_exception('invalidcoursemodule'); } // Checking course instance $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); require_course_login($course, true, $cm); $groupmode = groups_get_activity_groupmode($cm); // This is where people will land when they change groups using the drop-down selector. // Set the activity group so tabs and content are shown correctly. $currentgroup = groups_get_activity_group($cm, true); if ($wiki->wikimode == 'individual' && ($groupmode == SEPARATEGROUPS || $groupmode == VISIBLEGROUPS)) { list($gid, $uid) = explode('-', $groupanduser); } else if ($wiki->wikimode == 'individual') { $gid = 0; $uid = $userid; } else if ($groupmode == NOGROUPS) { $gid = 0; $uid = 0; } else { $gid = $currentgroup; $uid = 0; } // Getting subwiki instance. If it does not exists, redirect to create page if (!$subwiki = wiki_get_subwiki_by_group($wiki->id, $gid, $uid)) { $context = context_module::instance($cm->id); $modeanduser = $wiki->wikimode == 'individual' && $uid != $USER->id; $modeandgroupmember = $wiki->wikimode == 'collaborative' && !groups_is_member($gid); $manage = has_capability('mod/wiki:managewiki', $context); $edit = has_capability('mod/wiki:editpage', $context); $manageandedit = $manage && $edit; if ($groupmode == VISIBLEGROUPS and ($modeanduser || $modeandgroupmember) and !$manageandedit) { throw new \moodle_exception('nocontent', 'wiki'); } $params = array('wid' => $wiki->id, 'group' => $gid, 'uid' => $uid, 'title' => $title); $url = new moodle_url('/mod/wiki/create.php', $params); redirect($url); } // Checking is there is a page with this title. If it does not exists, redirect to first page if (!$page = wiki_get_page_by_title($subwiki->id, $title)) { $params = array('wid' => $wiki->id, 'group' => $gid, 'uid' => $uid, 'title' => $wiki->firstpagetitle); // Check to see if the first page has been created if (!wiki_get_page_by_title($subwiki->id, $wiki->firstpagetitle)) { $url = new moodle_url('/mod/wiki/create.php', $params); } else { $url = new moodle_url('/mod/wiki/view.php', $params); } redirect($url); } // /* // * Case 3: // * // * A user switches group when is 'reading' a non-existent page. // * // * URL Params: wid -> wiki id // * title -> page title // * currentgroup -> group id // * // */ //} elseif ($wid && $title && $currentgroup) { // // // Checking wiki instance // if (!$wiki = wiki_get_wiki($wid)) { // throw new \moodle_exception('incorrectwikiid', 'wiki'); // } // // // Checking subwiki instance // // @TODO: Fix call to wiki_get_subwiki_by_group // if (!$currentgroup = groups_get_activity_group($cm)){ // $currentgroup = 0; // } // if (!$subwiki = wiki_get_subwiki_by_group($wid, $currentgroup)) { // throw new \moodle_exception('incorrectsubwikiid', 'wiki'); // } // // // Checking page instance // if ($page = wiki_get_page_by_title($subwiki->id, $title)) { // unset($title); // } // // // Checking course instance // $course = $DB->get_record('course', array('id'=>$cm->course), '*', MUST_EXIST); // // // Checking course module instance // if (!$cm = get_coursemodule_from_instance("wiki", $wiki->id, $course->id)) { // throw new \moodle_exception('invalidcoursemodule'); // } // // $subwiki = null; // $page = null; // // /* // * Case 4: // * // * Error. No more options // */ } else { throw new \moodle_exception('invalidparameters', 'wiki'); } if (!wiki_user_can_view($subwiki, $wiki)) { throw new \moodle_exception('cannotviewpage', 'wiki'); } if (($edit != - 1) and $PAGE->user_allowed_editing()) { $USER->editing = $edit; } $wikipage = new page_wiki_view($wiki, $subwiki, $cm); $wikipage->set_gid($currentgroup); $wikipage->set_page($page); $context = context_module::instance($cm->id); if ($pageid) { wiki_page_view($wiki, $page, $course, $cm, $context, null, null, $subwiki); } else if ($id) { wiki_view($wiki, $course, $cm, $context); } else if ($wid && $title) { $other = array( 'title' => $title, 'wid' => $wid, 'group' => $gid, 'groupanduser' => $groupanduser ); wiki_page_view($wiki, $page, $course, $cm, $context, $uid, $other, $subwiki); } $wikipage->print_header(); $wikipage->print_content(); $wikipage->print_footer(); edit_form.php000064400000012345152265517660007251 0ustar00. /** * This file contains all necessary code to define and process an edit form * * @package mod_wiki * @copyright 2009 Marc Alier, Jordi Piguillem marc.alier@upc.edu * @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu * * @author Josep Arus * * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ if (!defined('MOODLE_INTERNAL')) { die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page } require_once($CFG->dirroot . '/mod/wiki/editors/wikieditor.php'); class mod_wiki_edit_form extends moodleform { protected function definition() { global $CFG; $mform = $this->_form; // BEWARE HACK: In order for things to work we need to override the form id and set it to mform1. // The first form to be instantiated never gets displayed so this should be safe. $mform->updateAttributes(array('id' => 'mform1')); $version = $this->_customdata['version']; $format = $this->_customdata['format']; if (empty($this->_customdata['contextid'])) { // Hack alert // This is being done ONLY to aid those who may have created there own wiki pages. It should be removed sometime // after the release of 2.3 (not creating an issue because this whole thing should be reviewed) debugging('You must always provide mod_wiki_edit_form with a contextid in its custom data', DEBUG_DEVELOPER); global $PAGE; $contextid = $PAGE->context->id; } else { $contextid = $this->_customdata['contextid']; } if (isset($this->_customdata['pagetitle'])) { // Page title must be formatted properly here as this is output and not an element. $pagetitle = get_string('editingpage', 'wiki', format_string($this->_customdata['pagetitle'], true, array('context' => context::instance_by_id($contextid, MUST_EXIST)))); } else { $pagetitle = get_string('editing', 'wiki'); } //editor $mform->addElement('header', 'general', $pagetitle); $fieldname = get_string('format' . $format, 'wiki'); if ($format != 'html') { // Use wiki editor $extensions = file_get_typegroup('extension', 'web_image'); $fs = get_file_storage(); $tree = $fs->get_area_tree($contextid, 'mod_wiki', $this->_customdata['filearea'], $this->_customdata['fileitemid']); $files = array(); foreach ($tree['files'] as $file) { $filename = $file->get_filename(); foreach ($extensions as $ext) { if (preg_match('#'.$ext.'$#i', $filename)) { $files[] = $filename; } } } $mform->addElement('wikieditor', 'newcontent', $fieldname, array('cols' => 100, 'rows' => 20, 'wiki_format' => $format, 'files'=>$files)); $mform->addHelpButton('newcontent', 'format'.$format, 'wiki'); $mform->setType('newcontent', PARAM_RAW); // processed by trust text or cleaned before the display } else { $mform->addElement('editor', 'newcontent_editor', $fieldname, null, page_wiki_edit::$attachmentoptions); $mform->addHelpButton('newcontent_editor', 'formathtml', 'wiki'); $mform->setType('newcontent_editor', PARAM_RAW); // processed by trust text or cleaned before the display } //hiddens if ($version >= 0) { $mform->addElement('hidden', 'version', $version); $mform->setType('version', PARAM_FLOAT); } $mform->addElement('hidden', 'contentformat', $format); $mform->setType('contentformat', PARAM_ALPHANUMEXT); if (core_tag_tag::is_enabled('mod_wiki', 'wiki_pages')) { $mform->addElement('header', 'tagshdr', get_string('tags', 'tag')); } $mform->addElement('tags', 'tags', get_string('tags'), array('itemtype' => 'wiki_pages', 'component' => 'mod_wiki')); $buttongroup = array(); $buttongroup[] = $mform->createElement('submit', 'editoption', get_string('save', 'wiki'), array('id' => 'save')); $buttongroup[] = $mform->createElement('submit', 'editoption', get_string('preview'), array('id' => 'preview'), false); $buttongroup[] = $mform->createElement('submit', 'editoption', get_string('cancel'), array('id' => 'cancel'), false); $mform->addGroup($buttongroup, 'buttonar', '', array(' '), false); $mform->closeHeaderBefore('buttonar'); } } diff/diff_added_ends.gif000064400000000063152265517660011223 0ustar00GIF89a ! ,  jL;diff/diff_added_begins.gif000064400000000075152265517660011544 0ustar00GIF89a ! , {Z r>=;diff/difflib.php000064400000057440152265517660007615 0ustar00serial=$j; $V[$j]->hash=crc32($file2[$j]); } // Step 2 Sort by hash,serial ///////// usort($V,"ouwiki_diff_sort_v"); // Make it start from 1 again array_unshift($V,'bogus'); unset($V[0]); // $V is now an array including the line number 'serial' and hash // of each line in file 2, sorted by hash and then serial. // Step 3 Equivalence classes ///////// $E=array(); $E[0]=new StdClass; $E[0]->serial=0; $E[0]->last=true; for($j=1;$j<=$n;$j++) { $E[$j]=new StdClass; $E[$j]->serial=$V[$j]->serial; $E[$j]->last=$j===$n || $V[$j]->hash!==$V[$j+1]->hash; } // E is now an array sorted the same way as $V which includes // the line number 'serial' and whether or not that is the 'last' // line in the given equivalence class, i.e. set of identical lines // Step 4 For each line in file1, finds start of equivalence class ///////// $P=array(); for($i=1;$i<=$m;$i++) { // Find matching last entry from equivalence list $P[$i]=ouwiki_diff_find_last($V,$E,crc32($file1[$i])); } // P is now an array that finds the index (within $V) of the *first* // matching line in $V (referencing file 2, but not a line number, // because sorted in $V order) for each line in file 1. In other words // if you were to start at the P-value in $V and continue through, you // would find all the lines from file 2 that are equal to the given line // from file 1. // Step 5 Initialise vector of candidates ///////// // I do not trust PHP references further than I can throw them (preferably // at the idiot who came up with the idea) so I am using a separate array // to store candidates and all references are integers into that. $candidates=array(); $candidates[0]=new StdClass; $candidates[0]->a=0; $candidates[0]->b=0; $candidates[0]->previous=null; $candidates[1]=new StdClass; $candidates[1]->a=$m+1; $candidates[1]->b=$n+1; $candidates[1]->previous=null; $K=array(); $K[0]=0; // Ref to candidate 0 $K[1]=1; // Ref to candidate 1 $k=0; // Step 6 Merge stage ///////// for($i=1;$i<=$m;$i++) { if($P[$i]!==0) { ouwiki_diff_merge($K,$k,$i,$E,$P[$i],$candidates); } } // Step 7 ///////// $J=array(); for($i=1;$i<=$m;$i++) { $J[$i]=0; } // Step 8 Follow candidate chain to make nice representation ///////// $index=$K[$k]; while(!is_null($index)) { // Stop when we reach the first, dummy candidate if($candidates[$index]->a!=0) { $J[$candidates[$index]->a]=$candidates[$index]->b; } $index=$candidates[$index]->previous; } // Step 9 Get rid of 'jackpots' (hash collisions) ///////// for($i=1;$i<=$m;$i++) { if($J[$i]!=0 && $file1[$i]!=$file2[$J[$i]]) { $J[$i]=0; } } // Done! (Maybe.) return $J; } // Functions needed by parts of the algorithm ///////////////////////////////////////////// // Merge, from step 7 (Appendix A.3) function ouwiki_diff_merge(&$K,&$k,$i,&$E,$p,&$candidates) { $r=0; $c=$K[0]; while(true) { $j=$E[$p]->serial; // Paper says 'i' but this is wrong (OCR) // Binary search in $K from $r to $k $min=$r; $max=$k+1; while(true) { $try = (int)(($min+$max)/2); if($candidates[$K[$try]]->b >= $j) { $max=$try; } else if($candidates[$K[$try+1]]->b <= $j) { $min=$try+1; } else { // $try is less and $try+1 is more $s=$try; break; } if($max<=$min) { $s=-1; break; } } if($s>-1) { if($candidates[$K[$s+1]]->b > $j) { // Create new candidate $index=count($candidates); $candidates[$index]=new StdClass; $candidates[$index]->a=$i; $candidates[$index]->b=$j; $candidates[$index]->previous=$K[$s]; $K[$r]=$c; $r=$s+1; $c=$index; // Or should this go before? } if($s===$k) { $K[$k+2]=$K[$k+1]; $k++; break; } } if($E[$p]->last) { break; } $p++; } $K[$r]=$c; } // From Step 2 function ouwiki_diff_sort_v($a,$b) { if($a->hash < $b->hash) { return -1; } else if($a->hash > $b->hash) { return 1; } else if($a->serial < $b->serial) { return -1; } else if($a->serial > $b->serial) { return 1; } else { return 0; } } // From Step 4 function ouwiki_diff_find_last(&$V,&$E,$hash) { // Binary search in $V until we find something with $hash // Min = 1, array is 1-indexed $min=1; // Max = 1 higher than highest key end($V); $max=key($V)+1; while(true) { $try = (int)(($min+$max)/2); if($V[$try]->hash > $hash) { $max=$try; } else if($V[$try]->hash < $hash) { $min=$try+1; } else { // Equal break; } if($max<=$min) { // No matching line return 0; } } // Now check back in $E to find the first line of that equivalence class for($j=$try;!$E[$j-1]->last;$j--) ; return $j; } /////////////////////////// /** * Class representing one 'line' of HTML content for the purpose of * text comparison. */ class ouwiki_line { /** Array of ouwiki_words */ var $words=array(); /** * Construct line object based on a chunk of text. * @param string $data Text data that makes up this 'line'. (May include line breaks etc.) * @param int $linepos Position number for first character in text */ public function __construct($data,$linepos) { // 1. Turn things we don't want into spaces (so that positioning stays same) // Whitespace replaced with space $data=preg_replace('/\s/',' ',$data); // Various ways of writing non-breaking space replaced with space // Note that using a single param for replace only works because all // the search strings are 6 characters long $data=str_replace(array(' ',' ',' '),' ',$data); // Tags replaced with equal number of spaces $data = preg_replace_callback('/<.*?'.'>/', function($matches) { return preg_replace("/./", " ", $matches[0]); }, $data); // 2. Analyse string so that each space-separated thing // is counted as a 'word' (note these may not be real words, // for instance words may include punctuation at either end) $pos=0; while(true) { // Find a non-space $strlendata = strlen($data); for(;$pos < $strlendata && substr($data,$pos,1)===' ';$pos++) ; if($pos==$strlendata) { // No more content break; } // Aaaand find the next space after that $space2=strpos($data,' ',$pos); if($space2===false) { // No more spaces? Everything left must be a word $this->words[]=new ouwiki_word(substr($data,$pos),$pos+$linepos); break; } else { $this->words[]=new ouwiki_word(substr($data,$pos,$space2-$pos),$pos+$linepos); $pos=$space2; } } } /** * Old syntax of class constructor. Deprecated in PHP7. * * @deprecated since Moodle 3.1 */ public function ouwiki_line($data, $linepos) { debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER); self::__construct($data, $linepos); } /** * @return string Normalised string representation of this line object */ function get_as_string() { $result=''; foreach($this->words as $word) { if($result!=='') { $result.=' '; } $result.=$word->word; } return $result; } /** * Static function converts lines to strings. * @param array $lines Array of ouwiki_line * @return array Array of strings */ static function get_as_strings($lines) { $strings=array(); foreach($lines as $key=>$value) { $strings[$key]=$value->get_as_string(); } return $strings; } /** * @return True if there are no words in the line */ function is_empty() { return count($this->words)===0; } } /** * Represents single word for html comparison. Note that words * are just chunks of plain text and may not be actual words; * they could include punctuation or (if there was e.g. a span * in the middle of something) even be part-words. */ class ouwiki_word { /** Word as plain string */ var $word; /** Start position in original xhtml */ var $start; public function __construct($word,$start) { $this->word=$word; $this->start=$start; } /** * Old syntax of class constructor. Deprecated in PHP7. * * @deprecated since Moodle 3.1 */ public function ouwiki_word($word, $start) { debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER); self::__construct($word, $start); } } /** * Prepares XHTML content for text difference comparison. * @param string $content XHTML content [NO SLASHES] * @return array Array of ouwiki_line objects */ function ouwiki_diff_html_to_lines($content) { // These functions are a pain mostly because PHP preg_* don't provide // proper information as to the start/end position of matches. As a // consequence there is a lot of hackery going down. At every point we // replace things with spaces rather than getting rid, in order to store // positions within original content. // Get rid of all script, style, object tags (that might contain non-text // outside tags) $content=preg_replace_callback( '^(