2 // This file is part of Book module for Moodle - http://moodle.org/
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.
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.
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/>.
18 * Book module core interaction API
21 * @copyright 2004-2011 Petr Skoda {@link http://skodak.org}
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 defined('MOODLE_INTERNAL') || die;
28 * Returns list of available numbering types
31 function book_get_numbering_types() {
32 global $CFG; // required for the include
33 require_once(dirname(__FILE__).'/locallib.php');
36 BOOK_NUM_NONE => get_string('numbering0', 'mod_book'),
37 BOOK_NUM_NUMBERS => get_string('numbering1', 'mod_book'),
38 BOOK_NUM_BULLETS => get_string('numbering2', 'mod_book'),
39 BOOK_NUM_INDENTED => get_string('numbering3', 'mod_book')
44 * Returns all other caps used in module
47 function book_get_extra_capabilities() {
48 // used for group-members-only
49 return array('moodle/site:accessallgroups');
55 * @param stdClass $data
56 * @param stdClass $mform
57 * @return int new book instance id
59 function book_add_instance($data, $mform) {
62 $data->timecreated = time();
63 $data->timemodified = $data->timecreated;
64 if (!isset($data->customtitles)) {
65 $data->customtitles = 0;
68 return $DB->insert_record('book', $data);
72 * Update book instance.
74 * @param stdClass $data
75 * @param stdClass $mform
78 function book_update_instance($data, $mform) {
81 $data->timemodified = time();
82 $data->id = $data->instance;
83 if (!isset($data->customtitles)) {
84 $data->customtitles = 0;
87 $DB->update_record('book', $data);
89 $book = $DB->get_record('book', array('id'=>$data->id));
90 $DB->set_field('book', 'revision', $book->revision+1, array('id'=>$book->id));
97 * Given an ID of an instance of this module,
98 * this function will permanently delete the instance
99 * and any data that depends on it.
102 * @return bool success
104 function book_delete_instance($id) {
107 if (!$book = $DB->get_record('book', array('id'=>$id))) {
111 $DB->delete_records('book_chapters', array('bookid'=>$book->id));
112 $DB->delete_records('book', array('id'=>$book->id));
120 * @param stdClass $course
121 * @param stdClass $user
122 * @param stdClass $mod
123 * @param object $book
124 * @return object|null
126 function book_user_outline($course, $user, $mod, $book) {
129 if ($logs = $DB->get_records('log', array('userid'=>$user->id, 'module'=>'book',
130 'action'=>'view', 'info'=>$book->id), 'time ASC')) {
132 $numviews = count($logs);
133 $lastlog = array_pop($logs);
135 $result = new stdClass();
136 $result->info = get_string('numviews', '', $numviews);
137 $result->time = $lastlog->time;
145 * Print a detailed representation of what a user has done with
146 * a given particular instance of this module, for user activity reports.
148 * @param stdClass $course
149 * @param stdClass $user
150 * @param stdClass $mod
151 * @param stdClass $book
154 function book_user_complete($course, $user, $mod, $book) {
159 * Given a course and a time, this module should find recent activity
160 * that has occurred in book activities and print it out.
162 * @param stdClass $course
163 * @param bool $viewfullnames
164 * @param int $timestart
165 * @return bool true if there was output, or false is there was none
167 function book_print_recent_activity($course, $viewfullnames, $timestart) {
168 return false; // True if anything was printed, otherwise false
176 function book_cron () {
181 * No grading in book.
186 function book_grades($bookid) {
191 * Returns the users with data in one book
193 * @todo deprecated - to be deleted in 2.2
197 function book_get_participants($bookid) {
198 // Must return an array of user records (all data) who are participants
199 // for a given instance of book. Must include every user involved
200 // in the instance, independent of his role (student, teacher, admin...)
201 // See other modules as example.
207 * This function returns if a scale is being used by one book
208 * it it has support for grading and scales. Commented code should be
209 * modified if necessary. See book, glossary or journal modules
213 * @param int $scaleid
214 * @return boolean True if the scale is used by any journal
216 function book_scale_used($bookid,$scaleid) {
221 * Checks if scale is being used by any instance of book
223 * This is used to find out if scale used anywhere
225 * @param int $scaleid
226 * @return bool true if the scale is used by any book
228 function book_scale_used_anywhere($scaleid) {
233 * Return read actions.
236 function book_get_view_actions() {
237 global $CFG; // necessary for includes
239 $return = array('view', 'view all');
241 $plugins = get_plugin_list('booktool');
242 foreach($plugins as $plugin=>$dir) {
243 if (file_exists("$dir/lib.php")) {
244 require_once("$dir/lib.php");
246 $function = 'booktool_'.$plugin.'_get_view_actions';
247 if (function_exists($function)) {
248 if ($actions = $function()) {
249 $return = array_merge($return, $actions);
258 * Return write actions.
261 function book_get_post_actions() {
262 global $CFG; // necessary for includes
264 $return = array('update');
266 $plugins = get_plugin_list('booktool');
267 foreach($plugins as $plugin=>$dir) {
268 if (file_exists("$dir/lib.php")) {
269 require_once("$dir/lib.php");
271 $function = 'booktool_'.$plugin.'_get_post_actions';
272 if (function_exists($function)) {
273 if ($actions = $function()) {
274 $return = array_merge($return, $actions);
285 * @param string $feature FEATURE_xx constant for requested feature
286 * @return mixed True if module supports feature, false if not, null if doesn't know
288 function book_supports($feature) {
290 case FEATURE_MOD_ARCHETYPE: return MOD_ARCHETYPE_RESOURCE;
291 case FEATURE_GROUPS: return false;
292 case FEATURE_GROUPINGS: return false;
293 case FEATURE_GROUPMEMBERSONLY: return true;
294 case FEATURE_MOD_INTRO: return true;
295 case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
296 case FEATURE_GRADE_HAS_GRADE: return false;
297 case FEATURE_GRADE_OUTCOMES: return false;
298 case FEATURE_BACKUP_MOODLE2: return true;
300 default: return null;
305 * Adds module specific settings to the settings block
307 * @param settings_navigation $settingsnav The settings navigation object
308 * @param navigation_node $booknode The node to add module settings to
311 function book_extend_settings_navigation(settings_navigation $settingsnav, navigation_node $booknode) {
312 global $USER, $PAGE, $CFG, $DB, $OUTPUT;
314 if ($PAGE->cm->modname !== 'book') {
318 if (empty($PAGE->cm->context)) {
319 $PAGE->cm->context = get_context_instance(CONTEXT_MODULE, $PAGE->cm->instance);
322 $plugins = get_plugin_list('booktool');
323 foreach($plugins as $plugin=>$dir) {
324 if (file_exists("$dir/lib.php")) {
325 require_once("$dir/lib.php");
327 $function = 'booktool_'.$plugin.'_extend_settings_navigation';
328 if (function_exists($function)) {
329 $function($settingsnav, $booknode);
333 $params = $PAGE->url->params();
335 if (!empty($params['id']) and !empty($params['chapterid']) and has_capability('mod/book:edit', $PAGE->cm->context)) {
336 if (!empty($USER->editing)) {
337 $string = get_string("turneditingoff");
340 $string = get_string("turneditingon");
343 $url = new moodle_url('/mod/book/view.php', array('id'=>$params['id'], 'chapterid'=>$params['chapterid'], 'edit'=>$edit, 'sesskey'=>sesskey()));
344 $booknode->add($string, $url, navigation_node::TYPE_SETTING);
350 * Lists all browsable file areas
351 * @param object $course
353 * @param object $context
356 function book_get_file_areas($course, $cm, $context) {
358 $areas['chapter'] = get_string('chapters', 'mod_book');
363 * File browsing support for book module ontent area.
364 * @param object $browser
365 * @param object $areas
366 * @param object $course
368 * @param object $context
369 * @param string $filearea
371 * @param string $filepath
372 * @param string $filename
373 * @return object file_info instance or null if not found
375 function book_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
378 // note: 'intro' area is handled in file_browser automatically
380 if (!has_capability('mod/book:read', $context)) {
384 if ($filearea !== 'chapter') {
388 require_once("$CFG->dirroot/mod/book/locallib.php");
390 if (is_null($itemid)) {
391 return new book_file_info($browser, $course, $cm, $context, $areas, $filearea);
394 $fs = get_file_storage();
395 $filepath = is_null($filepath) ? '/' : $filepath;
396 $filename = is_null($filename) ? '.' : $filename;
397 if (!$storedfile = $fs->get_file($context->id, 'mod_book', $filearea, $itemid, $filepath, $filename)) {
401 // modifications may be tricky - may cause caching problems
402 $canwrite = has_capability('mod/book:edit', $context);
404 $chaptername = $DB->get_field('book_chapters', 'title', array('bookid'=>$cm->instance, 'id'=>$itemid));
405 $chaptername = format_string($chaptername, true, array('context'=>$context));
407 $urlbase = $CFG->wwwroot.'/pluginfile.php';
408 return new file_info_stored($browser, $context, $storedfile, $urlbase, $chaptername, true, true, $canwrite, false);
412 * Serves the book attachments. Implements needed access control ;-)
414 * @param object $course
416 * @param object $context
417 * @param string $filearea
419 * @param bool $forcedownload
420 * @return bool false if file not found, does not return if found - just send the file
422 function book_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) {
425 if ($context->contextlevel != CONTEXT_MODULE) {
429 require_course_login($course, true, $cm);
431 if ($filearea !== 'chapter') {
435 if (!has_capability('mod/book:read', $context)) {
439 $chid = (int)array_shift($args);
441 if (!$book = $DB->get_record('book', array('id'=>$cm->instance))) {
445 if (!$chapter = $DB->get_record('book_chapters', array('id'=>$chid, 'bookid'=>$book->id))) {
449 if ($chapter->hidden and !has_capability('mod/book:viewhiddenchapters', $context)) {
453 $fs = get_file_storage();
454 $relativepath = implode('/', $args);
455 $fullpath = "/$context->id/mod_book/chapter/$chid/$relativepath";
456 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
460 // finally send the file
461 send_stored_file($file, 360, 0, false);
465 * Return a list of page types
467 * @param string $pagetype current page type
468 * @param stdClass $parentcontext Block's parent context
469 * @param stdClass $currentcontext Current context of block
472 function book_page_type_list($pagetype, $parentcontext, $currentcontext) {
473 $module_pagetype = array('mod-book-*'=>get_string('page-mod-book-x', 'mod_book'));
474 return $module_pagetype;