[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Book module core interaction API 19 * 20 * @package mod_book 21 * @copyright 2004-2011 Petr Skoda {@link http://skodak.org} 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die; 26 27 /** 28 * Returns list of available numbering types 29 * @return array 30 */ 31 function book_get_numbering_types() { 32 global $CFG; // required for the include 33 34 require_once (__DIR__.'/locallib.php'); 35 36 return array ( 37 BOOK_NUM_NONE => get_string('numbering0', 'mod_book'), 38 BOOK_NUM_NUMBERS => get_string('numbering1', 'mod_book'), 39 BOOK_NUM_BULLETS => get_string('numbering2', 'mod_book'), 40 BOOK_NUM_INDENTED => get_string('numbering3', 'mod_book') 41 ); 42 } 43 44 /** 45 * Returns list of available navigation link types. 46 * @return array 47 */ 48 function book_get_nav_types() { 49 require_once (__DIR__.'/locallib.php'); 50 51 return array ( 52 BOOK_LINK_TOCONLY => get_string('navtoc', 'mod_book'), 53 BOOK_LINK_IMAGE => get_string('navimages', 'mod_book'), 54 BOOK_LINK_TEXT => get_string('navtext', 'mod_book'), 55 ); 56 } 57 58 /** 59 * Returns list of available navigation link CSS classes. 60 * @return array 61 */ 62 function book_get_nav_classes() { 63 return array ('navtoc', 'navimages', 'navtext'); 64 } 65 66 /** 67 * Returns all other caps used in module 68 * @return array 69 */ 70 function book_get_extra_capabilities() { 71 // used for group-members-only 72 return array('moodle/site:accessallgroups'); 73 } 74 75 /** 76 * Add book instance. 77 * 78 * @param stdClass $data 79 * @param stdClass $mform 80 * @return int new book instance id 81 */ 82 function book_add_instance($data, $mform) { 83 global $DB; 84 85 $data->timecreated = time(); 86 $data->timemodified = $data->timecreated; 87 if (!isset($data->customtitles)) { 88 $data->customtitles = 0; 89 } 90 91 return $DB->insert_record('book', $data); 92 } 93 94 /** 95 * Update book instance. 96 * 97 * @param stdClass $data 98 * @param stdClass $mform 99 * @return bool true 100 */ 101 function book_update_instance($data, $mform) { 102 global $DB; 103 104 $data->timemodified = time(); 105 $data->id = $data->instance; 106 if (!isset($data->customtitles)) { 107 $data->customtitles = 0; 108 } 109 110 $DB->update_record('book', $data); 111 112 $book = $DB->get_record('book', array('id'=>$data->id)); 113 $DB->set_field('book', 'revision', $book->revision+1, array('id'=>$book->id)); 114 115 return true; 116 } 117 118 /** 119 * Delete book instance by activity id 120 * 121 * @param int $id 122 * @return bool success 123 */ 124 function book_delete_instance($id) { 125 global $DB; 126 127 if (!$book = $DB->get_record('book', array('id'=>$id))) { 128 return false; 129 } 130 131 $DB->delete_records('book_chapters', array('bookid'=>$book->id)); 132 $DB->delete_records('book', array('id'=>$book->id)); 133 134 return true; 135 } 136 137 /** 138 * Given a course and a time, this module should find recent activity 139 * that has occurred in book activities and print it out. 140 * 141 * @param stdClass $course 142 * @param bool $viewfullnames 143 * @param int $timestart 144 * @return bool true if there was output, or false is there was none 145 */ 146 function book_print_recent_activity($course, $viewfullnames, $timestart) { 147 return false; // True if anything was printed, otherwise false 148 } 149 150 /** 151 * This function is used by the reset_course_userdata function in moodlelib. 152 * @param $data the data submitted from the reset course. 153 * @return array status array 154 */ 155 function book_reset_userdata($data) { 156 return array(); 157 } 158 159 /** 160 * No cron in book. 161 * 162 * @return bool 163 */ 164 function book_cron () { 165 return true; 166 } 167 168 /** 169 * No grading in book. 170 * 171 * @param int $bookid 172 * @return null 173 */ 174 function book_grades($bookid) { 175 return null; 176 } 177 178 /** 179 * This function returns if a scale is being used by one book 180 * it it has support for grading and scales. Commented code should be 181 * modified if necessary. See book, glossary or journal modules 182 * as reference. 183 * 184 * @param int $bookid 185 * @param int $scaleid 186 * @return boolean True if the scale is used by any journal 187 */ 188 function book_scale_used($bookid, $scaleid) { 189 return false; 190 } 191 192 /** 193 * Checks if scale is being used by any instance of book 194 * 195 * This is used to find out if scale used anywhere 196 * 197 * @param int $scaleid 198 * @return bool true if the scale is used by any book 199 */ 200 function book_scale_used_anywhere($scaleid) { 201 return false; 202 } 203 204 /** 205 * Return read actions. 206 * 207 * Note: This is not used by new logging system. Event with 208 * crud = 'r' and edulevel = LEVEL_PARTICIPATING will 209 * be considered as view action. 210 * 211 * @return array 212 */ 213 function book_get_view_actions() { 214 global $CFG; // necessary for includes 215 216 $return = array('view', 'view all'); 217 218 $plugins = core_component::get_plugin_list('booktool'); 219 foreach ($plugins as $plugin => $dir) { 220 if (file_exists("$dir/lib.php")) { 221 require_once("$dir/lib.php"); 222 } 223 $function = 'booktool_'.$plugin.'_get_view_actions'; 224 if (function_exists($function)) { 225 if ($actions = $function()) { 226 $return = array_merge($return, $actions); 227 } 228 } 229 } 230 231 return $return; 232 } 233 234 /** 235 * Return write actions. 236 * 237 * Note: This is not used by new logging system. Event with 238 * crud = ('c' || 'u' || 'd') and edulevel = LEVEL_PARTICIPATING 239 * will be considered as post action. 240 * 241 * @return array 242 */ 243 function book_get_post_actions() { 244 global $CFG; // necessary for includes 245 246 $return = array('update'); 247 248 $plugins = core_component::get_plugin_list('booktool'); 249 foreach ($plugins as $plugin => $dir) { 250 if (file_exists("$dir/lib.php")) { 251 require_once("$dir/lib.php"); 252 } 253 $function = 'booktool_'.$plugin.'_get_post_actions'; 254 if (function_exists($function)) { 255 if ($actions = $function()) { 256 $return = array_merge($return, $actions); 257 } 258 } 259 } 260 261 return $return; 262 } 263 264 /** 265 * Supported features 266 * 267 * @param string $feature FEATURE_xx constant for requested feature 268 * @return mixed True if module supports feature, false if not, null if doesn't know 269 */ 270 function book_supports($feature) { 271 switch($feature) { 272 case FEATURE_MOD_ARCHETYPE: return MOD_ARCHETYPE_RESOURCE; 273 case FEATURE_GROUPS: return false; 274 case FEATURE_GROUPINGS: return false; 275 case FEATURE_MOD_INTRO: return true; 276 case FEATURE_COMPLETION_TRACKS_VIEWS: return true; 277 case FEATURE_GRADE_HAS_GRADE: return false; 278 case FEATURE_GRADE_OUTCOMES: return false; 279 case FEATURE_BACKUP_MOODLE2: return true; 280 case FEATURE_SHOW_DESCRIPTION: return true; 281 282 default: return null; 283 } 284 } 285 286 /** 287 * Adds module specific settings to the settings block 288 * 289 * @param settings_navigation $settingsnav The settings navigation object 290 * @param navigation_node $booknode The node to add module settings to 291 * @return void 292 */ 293 function book_extend_settings_navigation(settings_navigation $settingsnav, navigation_node $booknode) { 294 global $USER, $PAGE; 295 296 $plugins = core_component::get_plugin_list('booktool'); 297 foreach ($plugins as $plugin => $dir) { 298 if (file_exists("$dir/lib.php")) { 299 require_once("$dir/lib.php"); 300 } 301 $function = 'booktool_'.$plugin.'_extend_settings_navigation'; 302 if (function_exists($function)) { 303 $function($settingsnav, $booknode); 304 } 305 } 306 307 $params = $PAGE->url->params(); 308 309 if (!empty($params['id']) and !empty($params['chapterid']) and has_capability('mod/book:edit', $PAGE->cm->context)) { 310 if (!empty($USER->editing)) { 311 $string = get_string("turneditingoff"); 312 $edit = '0'; 313 } else { 314 $string = get_string("turneditingon"); 315 $edit = '1'; 316 } 317 $url = new moodle_url('/mod/book/view.php', array('id'=>$params['id'], 'chapterid'=>$params['chapterid'], 'edit'=>$edit, 'sesskey'=>sesskey())); 318 $booknode->add($string, $url, navigation_node::TYPE_SETTING); 319 } 320 } 321 322 323 /** 324 * Lists all browsable file areas 325 * @param object $course 326 * @param object $cm 327 * @param object $context 328 * @return array 329 */ 330 function book_get_file_areas($course, $cm, $context) { 331 $areas = array(); 332 $areas['chapter'] = get_string('chapters', 'mod_book'); 333 return $areas; 334 } 335 336 /** 337 * File browsing support for book module chapter area. 338 * @param object $browser 339 * @param object $areas 340 * @param object $course 341 * @param object $cm 342 * @param object $context 343 * @param string $filearea 344 * @param int $itemid 345 * @param string $filepath 346 * @param string $filename 347 * @return object file_info instance or null if not found 348 */ 349 function book_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) { 350 global $CFG, $DB; 351 352 // note: 'intro' area is handled in file_browser automatically 353 354 if (!has_capability('mod/book:read', $context)) { 355 return null; 356 } 357 358 if ($filearea !== 'chapter') { 359 return null; 360 } 361 362 require_once (__DIR__.'/locallib.php'); 363 364 if (is_null($itemid)) { 365 return new book_file_info($browser, $course, $cm, $context, $areas, $filearea); 366 } 367 368 $fs = get_file_storage(); 369 $filepath = is_null($filepath) ? '/' : $filepath; 370 $filename = is_null($filename) ? '.' : $filename; 371 if (!$storedfile = $fs->get_file($context->id, 'mod_book', $filearea, $itemid, $filepath, $filename)) { 372 return null; 373 } 374 375 // modifications may be tricky - may cause caching problems 376 $canwrite = has_capability('mod/book:edit', $context); 377 378 $chaptername = $DB->get_field('book_chapters', 'title', array('bookid'=>$cm->instance, 'id'=>$itemid)); 379 $chaptername = format_string($chaptername, true, array('context'=>$context)); 380 381 $urlbase = $CFG->wwwroot.'/pluginfile.php'; 382 return new file_info_stored($browser, $context, $storedfile, $urlbase, $chaptername, true, true, $canwrite, false); 383 } 384 385 /** 386 * Serves the book attachments. Implements needed access control ;-) 387 * 388 * @param stdClass $course course object 389 * @param cm_info $cm course module object 390 * @param context $context context object 391 * @param string $filearea file area 392 * @param array $args extra arguments 393 * @param bool $forcedownload whether or not force download 394 * @param array $options additional options affecting the file serving 395 * @return bool false if file not found, does not return if found - just send the file 396 */ 397 function book_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) { 398 global $CFG, $DB; 399 400 if ($context->contextlevel != CONTEXT_MODULE) { 401 return false; 402 } 403 404 require_course_login($course, true, $cm); 405 406 if ($filearea !== 'chapter') { 407 return false; 408 } 409 410 if (!has_capability('mod/book:read', $context)) { 411 return false; 412 } 413 414 $chid = (int)array_shift($args); 415 416 if (!$book = $DB->get_record('book', array('id'=>$cm->instance))) { 417 return false; 418 } 419 420 if (!$chapter = $DB->get_record('book_chapters', array('id'=>$chid, 'bookid'=>$book->id))) { 421 return false; 422 } 423 424 if ($chapter->hidden and !has_capability('mod/book:viewhiddenchapters', $context)) { 425 return false; 426 } 427 428 // Download the contents of a chapter as an html file. 429 if ($args[0] == 'index.html') { 430 $filename = "index.html"; 431 432 // We need to rewrite the pluginfile URLs so the media filters can work. 433 $content = file_rewrite_pluginfile_urls($chapter->content, 'webservice/pluginfile.php', $context->id, 'mod_book', 'chapter', 434 $chapter->id); 435 $formatoptions = new stdClass; 436 $formatoptions->noclean = true; 437 $formatoptions->overflowdiv = true; 438 $formatoptions->context = $context; 439 440 $content = format_text($content, $chapter->contentformat, $formatoptions); 441 442 // Remove @@PLUGINFILE@@/. 443 $options = array('reverse' => true); 444 $content = file_rewrite_pluginfile_urls($content, 'webservice/pluginfile.php', $context->id, 'mod_book', 'chapter', 445 $chapter->id, $options); 446 $content = str_replace('@@PLUGINFILE@@/', '', $content); 447 448 $titles = ""; 449 // Format the chapter titles. 450 if (!$book->customtitles) { 451 require_once (__DIR__.'/locallib.php'); 452 $chapters = book_preload_chapters($book); 453 454 if (!$chapter->subchapter) { 455 $currtitle = book_get_chapter_title($chapter->id, $chapters, $book, $context); 456 // Note that we can't use the $OUTPUT->heading() in WS_SERVER mode. 457 $titles = "<h3>$currtitle</h3>"; 458 } else { 459 $currtitle = book_get_chapter_title($chapters[$chapter->id]->parent, $chapters, $book, $context); 460 $currsubtitle = book_get_chapter_title($chapter->id, $chapters, $book, $context); 461 // Note that we can't use the $OUTPUT->heading() in WS_SERVER mode. 462 $titles = "<h3>$currtitle</h3>"; 463 $titles .= "<h4>$currsubtitle</h4>"; 464 } 465 } 466 467 $content = $titles . $content; 468 469 send_file($content, $filename, 0, 0, true, true); 470 } else { 471 $fs = get_file_storage(); 472 $relativepath = implode('/', $args); 473 $fullpath = "/$context->id/mod_book/chapter/$chid/$relativepath"; 474 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { 475 return false; 476 } 477 478 // Nasty hack because we do not have file revisions in book yet. 479 $lifetime = $CFG->filelifetime; 480 if ($lifetime > 60 * 10) { 481 $lifetime = 60 * 10; 482 } 483 484 // Finally send the file. 485 send_stored_file($file, $lifetime, 0, $forcedownload, $options); 486 } 487 } 488 489 /** 490 * Return a list of page types 491 * 492 * @param string $pagetype current page type 493 * @param stdClass $parentcontext Block's parent context 494 * @param stdClass $currentcontext Current context of block 495 * @return array 496 */ 497 function book_page_type_list($pagetype, $parentcontext, $currentcontext) { 498 $module_pagetype = array('mod-book-*'=>get_string('page-mod-book-x', 'mod_book')); 499 return $module_pagetype; 500 } 501 502 /** 503 * Export book resource contents 504 * 505 * @param stdClass $cm Course module object 506 * @param string $baseurl Base URL for file downloads 507 * @return array of file content 508 */ 509 function book_export_contents($cm, $baseurl) { 510 global $DB; 511 512 $contents = array(); 513 $context = context_module::instance($cm->id); 514 515 $book = $DB->get_record('book', array('id' => $cm->instance), '*', MUST_EXIST); 516 517 $fs = get_file_storage(); 518 519 $chapters = $DB->get_records('book_chapters', array('bookid' => $book->id), 'pagenum'); 520 521 $structure = array(); 522 $currentchapter = 0; 523 524 foreach ($chapters as $chapter) { 525 if ($chapter->hidden) { 526 continue; 527 } 528 529 // Generate the book structure. 530 $thischapter = array( 531 "title" => format_string($chapter->title, true, array('context' => $context)), 532 "href" => $chapter->id . "/index.html", 533 "level" => 0, 534 "subitems" => array() 535 ); 536 537 // Main chapter. 538 if (!$chapter->subchapter) { 539 $currentchapter = $chapter->pagenum; 540 $structure[$currentchapter] = $thischapter; 541 } else { 542 // Subchapter. 543 $thischapter['level'] = 1; 544 $structure[$currentchapter]["subitems"][] = $thischapter; 545 } 546 547 // Export the chapter contents. 548 549 // Main content (html). 550 $filename = 'index.html'; 551 $chapterindexfile = array(); 552 $chapterindexfile['type'] = 'file'; 553 $chapterindexfile['filename'] = $filename; 554 // Each chapter in a subdirectory. 555 $chapterindexfile['filepath'] = "/{$chapter->id}/"; 556 $chapterindexfile['filesize'] = 0; 557 $chapterindexfile['fileurl'] = moodle_url::make_webservice_pluginfile_url( 558 $context->id, 'mod_book', 'chapter', $chapter->id, '/', 'index.html')->out(false); 559 $chapterindexfile['timecreated'] = $book->timecreated; 560 $chapterindexfile['timemodified'] = $book->timemodified; 561 $chapterindexfile['content'] = format_string($chapter->title, true, array('context' => $context)); 562 $chapterindexfile['sortorder'] = 0; 563 $chapterindexfile['userid'] = null; 564 $chapterindexfile['author'] = null; 565 $chapterindexfile['license'] = null; 566 $contents[] = $chapterindexfile; 567 568 // Chapter files (images usually). 569 $files = $fs->get_area_files($context->id, 'mod_book', 'chapter', $chapter->id, 'sortorder DESC, id ASC', false); 570 foreach ($files as $fileinfo) { 571 $file = array(); 572 $file['type'] = 'file'; 573 $file['filename'] = $fileinfo->get_filename(); 574 $file['filepath'] = "/{$chapter->id}" . $fileinfo->get_filepath(); 575 $file['filesize'] = $fileinfo->get_filesize(); 576 $file['fileurl'] = moodle_url::make_webservice_pluginfile_url( 577 $context->id, 'mod_book', 'chapter', $chapter->id, 578 $fileinfo->get_filepath(), $fileinfo->get_filename())->out(false); 579 $file['timecreated'] = $fileinfo->get_timecreated(); 580 $file['timemodified'] = $fileinfo->get_timemodified(); 581 $file['sortorder'] = $fileinfo->get_sortorder(); 582 $file['userid'] = $fileinfo->get_userid(); 583 $file['author'] = $fileinfo->get_author(); 584 $file['license'] = $fileinfo->get_license(); 585 $contents[] = $file; 586 } 587 } 588 589 // First content is the structure in encoded JSON format. 590 $structurefile = array(); 591 $structurefile['type'] = 'content'; 592 $structurefile['filename'] = 'structure'; 593 $structurefile['filepath'] = "/"; 594 $structurefile['filesize'] = 0; 595 $structurefile['fileurl'] = null; 596 $structurefile['timecreated'] = $book->timecreated; 597 $structurefile['timemodified'] = $book->timemodified; 598 $structurefile['content'] = json_encode(array_values($structure)); 599 $structurefile['sortorder'] = 0; 600 $structurefile['userid'] = null; 601 $structurefile['author'] = null; 602 $structurefile['license'] = null; 603 604 // Add it as first element. 605 array_unshift($contents, $structurefile); 606 607 return $contents; 608 } 609 610 /** 611 * Mark the activity completed (if required) and trigger the course_module_viewed event. 612 * 613 * @param stdClass $book book object 614 * @param stdClass $chapter chapter object 615 * @param bool $islaschapter is the las chapter of the book? 616 * @param stdClass $course course object 617 * @param stdClass $cm course module object 618 * @param stdClass $context context object 619 * @since Moodle 3.0 620 */ 621 function book_view($book, $chapter, $islastchapter, $course, $cm, $context) { 622 623 // First case, we are just opening the book. 624 if (empty($chapter)) { 625 \mod_book\event\course_module_viewed::create_from_book($book, $context)->trigger(); 626 627 } else { 628 \mod_book\event\chapter_viewed::create_from_chapter($book, $context, $chapter)->trigger(); 629 630 if ($islastchapter) { 631 // We cheat a bit here in assuming that viewing the last page means the user viewed the whole book. 632 $completion = new completion_info($course); 633 $completion->set_module_viewed($cm); 634 } 635 } 636 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |