Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402]
1 <?php 2 3 // This file is part of Moodle - http://moodle.org/ 4 // 5 // Moodle is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // Moodle is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 17 18 /** 19 * Library of functions and constants for module wiki 20 * 21 * It contains the great majority of functions defined by Moodle 22 * that are mandatory to develop a module. 23 * 24 * @package mod_wiki 25 * @copyright 2009 Marc Alier, Jordi Piguillem marc.alier@upc.edu 26 * @copyright 2009 Universitat Politecnica de Catalunya http://www.upc.edu 27 * 28 * @author Jordi Piguillem 29 * @author Marc Alier 30 * @author David Jimenez 31 * @author Josep Arus 32 * @author Kenneth Riba 33 * 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 */ 36 37 defined('MOODLE_INTERNAL') || die(); 38 39 /** 40 * Given an object containing all the necessary data, 41 * (defined by the form in mod.html) this function 42 * will create a new instance and return the id number 43 * of the new instance. 44 * 45 * @param object $instance An object from the form in mod.html 46 * @return int The id of the newly inserted wiki record 47 **/ 48 function wiki_add_instance($wiki) { 49 global $DB; 50 51 $wiki->timemodified = time(); 52 # May have to add extra stuff in here # 53 if (empty($wiki->forceformat)) { 54 $wiki->forceformat = 0; 55 } 56 57 $id = $DB->insert_record('wiki', $wiki); 58 59 $completiontimeexpected = !empty($wiki->completionexpected) ? $wiki->completionexpected : null; 60 \core_completion\api::update_completion_date_event($wiki->coursemodule, 'wiki', $id, $completiontimeexpected); 61 62 return $id; 63 } 64 65 /** 66 * Given an object containing all the necessary data, 67 * (defined by the form in mod.html) this function 68 * will update an existing instance with new data. 69 * 70 * @param object $instance An object from the form in mod.html 71 * @return boolean Success/Fail 72 **/ 73 function wiki_update_instance($wiki) { 74 global $DB; 75 76 $wiki->timemodified = time(); 77 $wiki->id = $wiki->instance; 78 if (empty($wiki->forceformat)) { 79 $wiki->forceformat = 0; 80 } 81 82 $completiontimeexpected = !empty($wiki->completionexpected) ? $wiki->completionexpected : null; 83 \core_completion\api::update_completion_date_event($wiki->coursemodule, 'wiki', $wiki->id, $completiontimeexpected); 84 85 # May have to add extra stuff in here # 86 87 return $DB->update_record('wiki', $wiki); 88 } 89 90 /** 91 * Given an ID of an instance of this module, 92 * this function will permanently delete the instance 93 * and any data that depends on it. 94 * 95 * @param int $id Id of the module instance 96 * @return boolean Success/Failure 97 **/ 98 function wiki_delete_instance($id) { 99 global $DB; 100 101 if (!$wiki = $DB->get_record('wiki', array('id' => $id))) { 102 return false; 103 } 104 105 $result = true; 106 107 # Get subwiki information # 108 $subwikis = $DB->get_records('wiki_subwikis', array('wikiid' => $wiki->id)); 109 110 foreach ($subwikis as $subwiki) { 111 # Get existing links, and delete them # 112 if (!$DB->delete_records('wiki_links', array('subwikiid' => $subwiki->id), IGNORE_MISSING)) { 113 $result = false; 114 } 115 116 # Get existing pages # 117 if ($pages = $DB->get_records('wiki_pages', array('subwikiid' => $subwiki->id))) { 118 foreach ($pages as $page) { 119 # Get locks, and delete them # 120 if (!$DB->delete_records('wiki_locks', array('pageid' => $page->id), IGNORE_MISSING)) { 121 $result = false; 122 } 123 124 # Get versions, and delete them # 125 if (!$DB->delete_records('wiki_versions', array('pageid' => $page->id), IGNORE_MISSING)) { 126 $result = false; 127 } 128 } 129 130 # Delete pages # 131 if (!$DB->delete_records('wiki_pages', array('subwikiid' => $subwiki->id), IGNORE_MISSING)) { 132 $result = false; 133 } 134 } 135 136 # Get existing synonyms, and delete them # 137 if (!$DB->delete_records('wiki_synonyms', array('subwikiid' => $subwiki->id), IGNORE_MISSING)) { 138 $result = false; 139 } 140 141 # Delete any subwikis # 142 if (!$DB->delete_records('wiki_subwikis', array('id' => $subwiki->id), IGNORE_MISSING)) { 143 $result = false; 144 } 145 } 146 147 $cm = get_coursemodule_from_instance('wiki', $id); 148 \core_completion\api::update_completion_date_event($cm->id, 'wiki', $wiki->id, null); 149 150 # Delete any dependent records here # 151 if (!$DB->delete_records('wiki', array('id' => $wiki->id))) { 152 $result = false; 153 } 154 155 return $result; 156 } 157 158 /** 159 * Implements callback to reset course 160 * 161 * @param stdClass $data 162 * @return boolean|array 163 */ 164 function wiki_reset_userdata($data) { 165 global $CFG,$DB; 166 require_once($CFG->dirroot . '/mod/wiki/pagelib.php'); 167 require_once($CFG->dirroot . "/mod/wiki/locallib.php"); 168 169 $componentstr = get_string('modulenameplural', 'wiki'); 170 $status = array(); 171 172 //get the wiki(s) in this course. 173 if (!$wikis = $DB->get_records('wiki', array('course' => $data->courseid))) { 174 return false; 175 } 176 if (empty($data->reset_wiki_comments) && empty($data->reset_wiki_tags) && empty($data->reset_wiki_pages)) { 177 return $status; 178 } 179 180 foreach ($wikis as $wiki) { 181 if (!$cm = get_coursemodule_from_instance('wiki', $wiki->id, $data->courseid)) { 182 continue; 183 } 184 $context = context_module::instance($cm->id); 185 186 // Remove tags or all pages. 187 if (!empty($data->reset_wiki_pages) || !empty($data->reset_wiki_tags)) { 188 189 // Get subwiki information. 190 $subwikis = wiki_get_subwikis($wiki->id); 191 192 foreach ($subwikis as $subwiki) { 193 // Get existing pages. 194 if ($pages = wiki_get_page_list($subwiki->id)) { 195 // If the wiki page isn't selected then we are only removing tags. 196 if (empty($data->reset_wiki_pages)) { 197 // Go through each page and delete the tags. 198 foreach ($pages as $page) { 199 core_tag_tag::remove_all_item_tags('mod_wiki', 'wiki_pages', $page->id); 200 } 201 } else { 202 // Otherwise we are removing pages and tags. 203 wiki_delete_pages($context, $pages, $subwiki->id); 204 } 205 } 206 if (!empty($data->reset_wiki_pages)) { 207 // Delete any subwikis. 208 $DB->delete_records('wiki_subwikis', array('id' => $subwiki->id), IGNORE_MISSING); 209 210 // Delete any attached files. 211 $fs = get_file_storage(); 212 $fs->delete_area_files($context->id, 'mod_wiki', 'attachments'); 213 } 214 } 215 216 if (!empty($data->reset_wiki_pages)) { 217 $status[] = array('component' => $componentstr, 'item' => get_string('deleteallpages', 'wiki'), 218 'error' => false); 219 } 220 if (!empty($data->reset_wiki_tags)) { 221 $status[] = array('component' => $componentstr, 'item' => get_string('tagsdeleted', 'wiki'), 'error' => false); 222 } 223 } 224 225 // Remove all comments. 226 if (!empty($data->reset_wiki_comments) || !empty($data->reset_wiki_pages)) { 227 $DB->delete_records_select('comments', "contextid = ? AND commentarea='wiki_page'", array($context->id)); 228 if (!empty($data->reset_wiki_comments)) { 229 $status[] = array('component' => $componentstr, 'item' => get_string('deleteallcomments'), 'error' => false); 230 } 231 } 232 } 233 234 // Any changes to the list of dates that needs to be rolled should be same during course restore and course reset. 235 // See MDL-9367. 236 shift_course_mod_dates('wiki', array('editbegin', 'editend'), $data->timeshift, $data->courseid); 237 $status[] = array('component' => $componentstr, 'item' => get_string('datechanged'), 'error' => false); 238 239 return $status; 240 } 241 242 243 function wiki_reset_course_form_definition(&$mform) { 244 $mform->addElement('header', 'wikiheader', get_string('modulenameplural', 'wiki')); 245 $mform->addElement('advcheckbox', 'reset_wiki_pages', get_string('deleteallpages', 'wiki')); 246 $mform->addElement('advcheckbox', 'reset_wiki_tags', get_string('removeallwikitags', 'wiki')); 247 $mform->addElement('advcheckbox', 'reset_wiki_comments', get_string('deleteallcomments')); 248 } 249 250 /** 251 * Indicates API features that the wiki supports. 252 * 253 * @uses FEATURE_GROUPS 254 * @uses FEATURE_GROUPINGS 255 * @uses FEATURE_MOD_INTRO 256 * @uses FEATURE_COMPLETION_TRACKS_VIEWS 257 * @uses FEATURE_COMPLETION_HAS_RULES 258 * @uses FEATURE_GRADE_HAS_GRADE 259 * @uses FEATURE_GRADE_OUTCOMES 260 * @param string $feature 261 * @return mixed True if module supports feature, false if not, null if doesn't know or string for the module purpose. 262 */ 263 function wiki_supports($feature) { 264 switch ($feature) { 265 case FEATURE_GROUPS: 266 return true; 267 case FEATURE_GROUPINGS: 268 return true; 269 case FEATURE_MOD_INTRO: 270 return true; 271 case FEATURE_COMPLETION_TRACKS_VIEWS: 272 return true; 273 case FEATURE_GRADE_HAS_GRADE: 274 return false; 275 case FEATURE_GRADE_OUTCOMES: 276 return false; 277 case FEATURE_RATE: 278 return false; 279 case FEATURE_BACKUP_MOODLE2: 280 return true; 281 case FEATURE_SHOW_DESCRIPTION: 282 return true; 283 case FEATURE_COMMENT: 284 return true; 285 case FEATURE_MOD_PURPOSE: 286 return MOD_PURPOSE_COLLABORATION; 287 288 default: 289 return null; 290 } 291 } 292 293 /** 294 * Given a course and a time, this module should find recent activity 295 * that has occurred in wiki activities and print it out. 296 * Return true if there was output, or false is there was none. 297 * 298 * @global $CFG 299 * @global $DB 300 * @uses CONTEXT_MODULE 301 * @uses VISIBLEGROUPS 302 * @param object $course 303 * @param bool $viewfullnames capability 304 * @param int $timestart 305 * @return boolean 306 **/ 307 function wiki_print_recent_activity($course, $viewfullnames, $timestart) { 308 global $CFG, $DB, $OUTPUT; 309 310 $sql = "SELECT p.id, p.timemodified, p.subwikiid, sw.wikiid, w.wikimode, sw.userid, sw.groupid 311 FROM {wiki_pages} p 312 JOIN {wiki_subwikis} sw ON sw.id = p.subwikiid 313 JOIN {wiki} w ON w.id = sw.wikiid 314 WHERE p.timemodified > ? AND w.course = ? 315 ORDER BY p.timemodified ASC"; 316 if (!$pages = $DB->get_records_sql($sql, array($timestart, $course->id))) { 317 return false; 318 } 319 require_once($CFG->dirroot . "/mod/wiki/locallib.php"); 320 321 $wikis = array(); 322 323 $modinfo = get_fast_modinfo($course); 324 325 $subwikivisible = array(); 326 foreach ($pages as $page) { 327 if (!isset($subwikivisible[$page->subwikiid])) { 328 $subwiki = (object)array('id' => $page->subwikiid, 'wikiid' => $page->wikiid, 329 'groupid' => $page->groupid, 'userid' => $page->userid); 330 $wiki = (object)array('id' => $page->wikiid, 'course' => $course->id, 'wikimode' => $page->wikimode); 331 $subwikivisible[$page->subwikiid] = wiki_user_can_view($subwiki, $wiki); 332 } 333 if ($subwikivisible[$page->subwikiid]) { 334 $wikis[] = $page; 335 } 336 } 337 unset($subwikivisible); 338 unset($pages); 339 340 if (!$wikis) { 341 return false; 342 } 343 echo $OUTPUT->heading(get_string("updatedwikipages", 'wiki') . ':', 6); 344 foreach ($wikis as $wiki) { 345 $cm = $modinfo->instances['wiki'][$wiki->wikiid]; 346 $link = $CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $wiki->id; 347 print_recent_activity_note($wiki->timemodified, $wiki, $cm->name, $link, false, $viewfullnames); 348 } 349 350 return true; // True if anything was printed, otherwise false 351 } 352 353 /** 354 * Must return an array of grades for a given instance of this module, 355 * indexed by user. It also returns a maximum allowed grade. 356 * 357 * Example: 358 * $return->grades = array of grades; 359 * $return->maxgrade = maximum allowed grade; 360 * 361 * return $return; 362 * 363 * @param int $wikiid ID of an instance of this module 364 * @return mixed Null or object with an array of grades and with the maximum grade 365 **/ 366 function wiki_grades($wikiid) { 367 return null; 368 } 369 370 /** 371 * @deprecated since Moodle 3.8 372 */ 373 function wiki_scale_used() { 374 throw new coding_exception('wiki_scale_used() can not be used anymore. Plugins can implement ' . 375 '<modname>_scale_used_anywhere, all implementations of <modname>_scale_used are now ignored'); 376 } 377 378 /** 379 * Checks if scale is being used by any instance of wiki. 380 * This function was added in 1.9 381 * 382 * This is used to find out if scale used anywhere 383 * @param $scaleid int 384 * @return boolean True if the scale is used by any wiki 385 */ 386 function wiki_scale_used_anywhere($scaleid) { 387 global $DB; 388 389 //if ($scaleid and $DB->record_exists('wiki', array('grade' => -$scaleid))) { 390 // return true; 391 //} else { 392 // return false; 393 //} 394 395 return false; 396 } 397 398 /** 399 * file serving callback 400 * 401 * @copyright Josep Arus 402 * @package mod_wiki 403 * @category files 404 * @param stdClass $course course object 405 * @param stdClass $cm course module object 406 * @param stdClass $context context object 407 * @param string $filearea file area 408 * @param array $args extra arguments 409 * @param bool $forcedownload whether or not force download 410 * @param array $options additional options affecting the file serving 411 * @return bool false if the file was not found, just send the file otherwise and do not return anything 412 */ 413 function wiki_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) { 414 global $CFG; 415 416 if ($context->contextlevel != CONTEXT_MODULE) { 417 return false; 418 } 419 420 require_login($course, true, $cm); 421 422 require_once($CFG->dirroot . "/mod/wiki/locallib.php"); 423 424 if ($filearea == 'attachments') { 425 $swid = (int) array_shift($args); 426 427 if (!$subwiki = wiki_get_subwiki($swid)) { 428 return false; 429 } 430 431 require_capability('mod/wiki:viewpage', $context); 432 433 $relativepath = implode('/', $args); 434 435 $fullpath = "/$context->id/mod_wiki/attachments/$swid/$relativepath"; 436 437 $fs = get_file_storage(); 438 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { 439 return false; 440 } 441 442 send_stored_file($file, null, 0, $options); 443 } 444 } 445 446 /** 447 * Search for wiki 448 * 449 * @param stdClass $cm course module object 450 * @param string $search searchword. 451 * @param stdClass $subwiki Optional Subwiki. 452 * @return Search wiki input form 453 */ 454 function wiki_search_form($cm, $search = '', $subwiki = null) { 455 global $OUTPUT; 456 457 $hiddenfields = [ 458 (object) ['type' => 'hidden', 'name' => 'courseid', 'value' => $cm->course], 459 (object) ['type' => 'hidden', 'name' => 'cmid', 'value' => $cm->id], 460 (object) ['type' => 'hidden', 'name' => 'searchwikicontent', 'value' => 1], 461 ]; 462 if (!empty($subwiki->id)) { 463 $hiddenfields[] = (object) ['type' => 'hidden', 'name' => 'subwikiid', 'value' => $subwiki->id]; 464 } 465 $data = [ 466 'action' => new moodle_url('/mod/wiki/search.php'), 467 'hiddenfields' => $hiddenfields, 468 'inputname' => 'searchstring', 469 'query' => s($search, true), 470 'searchstring' => get_string('searchwikis', 'wiki'), 471 'extraclasses' => 'mt-2' 472 ]; 473 return $OUTPUT->render_from_template('core/search_input', $data); 474 } 475 476 /** 477 * Extends the global navigation tree by adding wiki nodes if there is a relevant content 478 * 479 * This can be called by an AJAX request so do not rely on $PAGE as it might not be set up properly. 480 * 481 * @param navigation_node $navref An object representing the navigation tree node of the workshop module instance 482 * @param stdClass $course the course object 483 * @param stdClass $instance the activity record object 484 * @param cm_info $cm the course module object 485 */ 486 function wiki_extend_navigation(navigation_node $navref, stdClass $course, stdClass $instance, cm_info $cm) { 487 global $CFG, $USER; 488 489 require_once($CFG->dirroot . '/mod/wiki/locallib.php'); 490 491 $context = context_module::instance($cm->id); 492 $userid = ($instance->wikimode == 'individual') ? $USER->id : 0; 493 $gid = groups_get_activity_group($cm) ?: 0; 494 495 if (!$subwiki = wiki_get_subwiki_by_group($cm->instance, $gid, $userid)) { 496 return; 497 } 498 499 $pageid = optional_param('pageid', null, PARAM_INT); 500 if (empty($pageid)) { 501 // wiki main page 502 $page = wiki_get_page_by_title($subwiki->id, $instance->firstpagetitle); 503 $pageid = $page->id; 504 } 505 506 if (wiki_can_create_pages($context)) { 507 $link = new moodle_url('/mod/wiki/create.php', ['action' => 'new', 'swid' => $subwiki->id]); 508 $navref->add(get_string('newpage', 'wiki'), $link, navigation_node::TYPE_SETTING); 509 } 510 511 if (empty($pageid)) { 512 return; 513 } 514 515 $canviewpage = has_capability('mod/wiki:viewpage', $context); 516 517 if ($canviewpage) { 518 $link = new moodle_url('/mod/wiki/view.php', ['pageid' => $pageid]); 519 $navref->add(get_string('view', 'wiki'), $link, navigation_node::TYPE_SETTING); 520 } 521 522 if (wiki_user_can_edit($subwiki)) { 523 $link = new moodle_url('/mod/wiki/edit.php', ['pageid' => $pageid]); 524 $navref->add(get_string('edit', 'wiki'), $link, navigation_node::TYPE_SETTING); 525 } 526 527 if (has_capability('mod/wiki:viewcomment', $context)) { 528 $link = new moodle_url('/mod/wiki/comments.php', ['pageid' => $pageid]); 529 $navref->add(get_string('comments', 'wiki'), $link, navigation_node::TYPE_SETTING); 530 } 531 532 if ($canviewpage) { 533 $link = new moodle_url('/mod/wiki/history.php', ['pageid' => $pageid]); 534 $navref->add(get_string('history', 'wiki'), $link, navigation_node::TYPE_SETTING); 535 536 $link = new moodle_url('/mod/wiki/map.php', ['pageid' => $pageid]); 537 $navref->add(get_string('map', 'wiki'), $link, navigation_node::TYPE_SETTING); 538 539 $link = new moodle_url('/mod/wiki/files.php', ['pageid' => $pageid]); 540 $navref->add(get_string('files', 'wiki'), $link, navigation_node::TYPE_SETTING); 541 } 542 543 if (has_capability('mod/wiki:managewiki', $context)) { 544 $link = new moodle_url('/mod/wiki/admin.php', ['pageid' => $pageid]); 545 $navref->add(get_string('admin', 'wiki'), $link, navigation_node::TYPE_SETTING); 546 } 547 } 548 /** 549 * Returns all other caps used in wiki module 550 * 551 * @return array 552 */ 553 function wiki_get_extra_capabilities() { 554 return array('moodle/comment:view', 'moodle/comment:post', 'moodle/comment:delete'); 555 } 556 557 /** 558 * Running addtional permission check on plugin, for example, plugins 559 * may have switch to turn on/off comments option, this callback will 560 * affect UI display, not like pluginname_comment_validate only throw 561 * exceptions. 562 * Capability check has been done in comment->check_permissions(), we 563 * don't need to do it again here. 564 * 565 * @package mod_wiki 566 * @category comment 567 * 568 * @param stdClass $comment_param { 569 * context => context the context object 570 * courseid => int course id 571 * cm => stdClass course module object 572 * commentarea => string comment area 573 * itemid => int itemid 574 * } 575 * @return array 576 */ 577 function wiki_comment_permissions($comment_param) { 578 return array('post'=>true, 'view'=>true); 579 } 580 581 /** 582 * Validate comment parameter before perform other comments actions 583 * 584 * @param stdClass $comment_param { 585 * context => context the context object 586 * courseid => int course id 587 * cm => stdClass course module object 588 * commentarea => string comment area 589 * itemid => int itemid 590 * } 591 * 592 * @package mod_wiki 593 * @category comment 594 * 595 * @return boolean 596 */ 597 function wiki_comment_validate($comment_param) { 598 global $DB, $CFG; 599 require_once($CFG->dirroot . '/mod/wiki/locallib.php'); 600 // validate comment area 601 if ($comment_param->commentarea != 'wiki_page') { 602 throw new comment_exception('invalidcommentarea'); 603 } 604 // validate itemid 605 if (!$record = $DB->get_record('wiki_pages', array('id'=>$comment_param->itemid))) { 606 throw new comment_exception('invalidcommentitemid'); 607 } 608 if (!$subwiki = wiki_get_subwiki($record->subwikiid)) { 609 throw new comment_exception('invalidsubwikiid'); 610 } 611 if (!$wiki = wiki_get_wiki_from_pageid($comment_param->itemid)) { 612 throw new comment_exception('invalidid', 'data'); 613 } 614 if (!$course = $DB->get_record('course', array('id'=>$wiki->course))) { 615 throw new comment_exception('coursemisconf'); 616 } 617 if (!$cm = get_coursemodule_from_instance('wiki', $wiki->id, $course->id)) { 618 throw new comment_exception('invalidcoursemodule'); 619 } 620 $context = context_module::instance($cm->id); 621 // group access 622 if ($subwiki->groupid) { 623 $groupmode = groups_get_activity_groupmode($cm, $course); 624 if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) { 625 if (!groups_is_member($subwiki->groupid)) { 626 throw new comment_exception('notmemberofgroup'); 627 } 628 } 629 } 630 // validate context id 631 if ($context->id != $comment_param->context->id) { 632 throw new comment_exception('invalidcontext'); 633 } 634 // validation for comment deletion 635 if (!empty($comment_param->commentid)) { 636 if ($comment = $DB->get_record('comments', array('id'=>$comment_param->commentid))) { 637 if ($comment->commentarea != 'wiki_page') { 638 throw new comment_exception('invalidcommentarea'); 639 } 640 if ($comment->contextid != $context->id) { 641 throw new comment_exception('invalidcontext'); 642 } 643 if ($comment->itemid != $comment_param->itemid) { 644 throw new comment_exception('invalidcommentitemid'); 645 } 646 } else { 647 throw new comment_exception('invalidcommentid'); 648 } 649 } 650 return true; 651 } 652 653 /** 654 * Return a list of page types 655 * @param string $pagetype current page type 656 * @param stdClass $parentcontext Block's parent context 657 * @param stdClass $currentcontext Current context of block 658 */ 659 function wiki_page_type_list($pagetype, $parentcontext, $currentcontext) { 660 $module_pagetype = array( 661 'mod-wiki-*'=>get_string('page-mod-wiki-x', 'wiki'), 662 'mod-wiki-view'=>get_string('page-mod-wiki-view', 'wiki'), 663 'mod-wiki-comments'=>get_string('page-mod-wiki-comments', 'wiki'), 664 'mod-wiki-history'=>get_string('page-mod-wiki-history', 'wiki'), 665 'mod-wiki-map'=>get_string('page-mod-wiki-map', 'wiki') 666 ); 667 return $module_pagetype; 668 } 669 670 /** 671 * Mark the activity completed (if required) and trigger the course_module_viewed event. 672 * 673 * @param stdClass $wiki Wiki object. 674 * @param stdClass $course Course object. 675 * @param stdClass $cm Course module object. 676 * @param stdClass $context Context object. 677 * @since Moodle 3.1 678 */ 679 function wiki_view($wiki, $course, $cm, $context) { 680 // Trigger course_module_viewed event. 681 $params = array( 682 'context' => $context, 683 'objectid' => $wiki->id 684 ); 685 $event = \mod_wiki\event\course_module_viewed::create($params); 686 $event->add_record_snapshot('course_modules', $cm); 687 $event->add_record_snapshot('course', $course); 688 $event->add_record_snapshot('wiki', $wiki); 689 $event->trigger(); 690 691 // Completion. 692 $completion = new completion_info($course); 693 $completion->set_module_viewed($cm); 694 } 695 696 /** 697 * Mark the activity completed (if required) and trigger the page_viewed event. 698 * 699 * @param stdClass $wiki Wiki object. 700 * @param stdClass $page Page object. 701 * @param stdClass $course Course object. 702 * @param stdClass $cm Course module object. 703 * @param stdClass $context Context object. 704 * @param int $uid Optional User ID. 705 * @param array $other Optional Other params: title, wiki ID, group ID, groupanduser, prettyview. 706 * @param stdClass $subwiki Optional Subwiki. 707 * @since Moodle 3.1 708 */ 709 function wiki_page_view($wiki, $page, $course, $cm, $context, $uid = null, $other = null, $subwiki = null) { 710 711 // Trigger course_module_viewed event. 712 $params = array( 713 'context' => $context, 714 'objectid' => $page->id 715 ); 716 if ($uid != null) { 717 $params['relateduserid'] = $uid; 718 } 719 if ($other != null) { 720 $params['other'] = $other; 721 } 722 723 $event = \mod_wiki\event\page_viewed::create($params); 724 725 $event->add_record_snapshot('wiki_pages', $page); 726 $event->add_record_snapshot('course_modules', $cm); 727 $event->add_record_snapshot('course', $course); 728 $event->add_record_snapshot('wiki', $wiki); 729 if ($subwiki != null) { 730 $event->add_record_snapshot('wiki_subwikis', $subwiki); 731 } 732 $event->trigger(); 733 734 // Completion. 735 $completion = new completion_info($course); 736 $completion->set_module_viewed($cm); 737 } 738 739 /** 740 * Check if the module has any update that affects the current user since a given time. 741 * 742 * @param cm_info $cm course module data 743 * @param int $from the time to check updates from 744 * @param array $filter if we need to check only specific updates 745 * @return stdClass an object with the different type of areas indicating if they were updated or not 746 * @since Moodle 3.2 747 */ 748 function wiki_check_updates_since(cm_info $cm, $from, $filter = array()) { 749 global $DB, $CFG; 750 require_once($CFG->dirroot . '/mod/wiki/locallib.php'); 751 752 $updates = new stdClass(); 753 if (!has_capability('mod/wiki:viewpage', $cm->context)) { 754 return $updates; 755 } 756 $updates = course_check_module_updates_since($cm, $from, array('attachments'), $filter); 757 758 // Check only pages updated in subwikis the user can access. 759 $updates->pages = (object) array('updated' => false); 760 $wiki = $DB->get_record($cm->modname, array('id' => $cm->instance), '*', MUST_EXIST); 761 if ($subwikis = wiki_get_visible_subwikis($wiki, $cm, $cm->context)) { 762 $subwikisids = array(); 763 foreach ($subwikis as $subwiki) { 764 $subwikisids[] = $subwiki->id; 765 } 766 list($subwikissql, $params) = $DB->get_in_or_equal($subwikisids, SQL_PARAMS_NAMED); 767 $select = 'subwikiid ' . $subwikissql . ' AND (timemodified > :since1 OR timecreated > :since2)'; 768 $params['since1'] = $from; 769 $params['since2'] = $from; 770 $pages = $DB->get_records_select('wiki_pages', $select, $params, '', 'id'); 771 if (!empty($pages)) { 772 $updates->pages->updated = true; 773 $updates->pages->itemids = array_keys($pages); 774 } 775 } 776 return $updates; 777 } 778 779 /** 780 * Get icon mapping for font-awesome. 781 */ 782 function mod_wiki_get_fontawesome_icon_map() { 783 return [ 784 'mod_wiki:attachment' => 'fa-paperclip', 785 ]; 786 } 787 788 /** 789 * This function receives a calendar event and returns the action associated with it, or null if there is none. 790 * 791 * This is used by block_myoverview in order to display the event appropriately. If null is returned then the event 792 * is not displayed on the block. 793 * 794 * @param calendar_event $event 795 * @param \core_calendar\action_factory $factory 796 * @param int $userid User id to use for all capability checks, etc. Set to 0 for current user (default). 797 * @return \core_calendar\local\event\entities\action_interface|null 798 */ 799 function mod_wiki_core_calendar_provide_event_action(calendar_event $event, 800 \core_calendar\action_factory $factory, 801 int $userid = 0) { 802 global $USER; 803 804 if (!$userid) { 805 $userid = $USER->id; 806 } 807 808 $cm = get_fast_modinfo($event->courseid, $userid)->instances['wiki'][$event->instance]; 809 810 if (!$cm->uservisible) { 811 // The module is not visible to the user for any reason. 812 return null; 813 } 814 815 $completion = new \completion_info($cm->get_course()); 816 817 $completiondata = $completion->get_data($cm, false, $userid); 818 819 if ($completiondata->completionstate != COMPLETION_INCOMPLETE) { 820 return null; 821 } 822 823 return $factory->create_instance( 824 get_string('view'), 825 new \moodle_url('/mod/wiki/view.php', ['id' => $cm->id]), 826 1, 827 true 828 ); 829 } 830 831 /** 832 * Sets dynamic information about a course module 833 * 834 * This callback is called from cm_info when checking module availability (incl. $cm->uservisible) 835 * 836 * Main viewing capability in mod_wiki is 'mod/wiki:viewpage' instead of the expected standardised 'mod/wiki:view'. 837 * The method cm_info::is_user_access_restricted_by_capability() does not work for wiki, we need to implement 838 * this callback. 839 * 840 * @param cm_info $cm 841 */ 842 function wiki_cm_info_dynamic(cm_info $cm) { 843 if (!has_capability('mod/wiki:viewpage', $cm->context, $cm->get_modinfo()->get_user_id())) { 844 $cm->set_available(false); 845 } 846 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body