849adeeba08ca31e8e45598aae7e026327dd162c
[moodle.git] / mod / book / lib.php
1 <?php
2 // This file is part of Book module for 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/>.
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  */
25 defined('MOODLE_INTERNAL') || die;
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     require_once(dirname(__FILE__).'/locallib.php');
35     return array (
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')
40     );
41 }
43 /**
44  * Returns all other caps used in module
45  * @return array
46  */
47 function book_get_extra_capabilities() {
48     // used for group-members-only
49     return array('moodle/site:accessallgroups');
50 }
52 /**
53  * Add book instance.
54  *
55  * @param stdClass $data
56  * @param stdClass $mform
57  * @return int new book instance id
58  */
59 function book_add_instance($data, $mform) {
60     global $DB;
62     $data->timecreated = time();
63     $data->timemodified = $data->timecreated;
64     if (!isset($data->customtitles)) {
65         $data->customtitles = 0;
66     }
68     return $DB->insert_record('book', $data);
69 }
71 /**
72  * Update book instance.
73  *
74  * @param stdClass $data
75  * @param stdClass $mform
76  * @return bool true
77  */
78 function book_update_instance($data, $mform) {
79     global $DB;
81     $data->timemodified = time();
82     $data->id = $data->instance;
83     if (!isset($data->customtitles)) {
84         $data->customtitles = 0;
85     }
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));
92     return true;
93 }
95 /**
96  *
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.
100  *
101  * @param int $id
102  * @return bool success
103  */
104 function book_delete_instance($id) {
105     global $DB;
107     if (!$book = $DB->get_record('book', array('id'=>$id))) {
108         return false;
109     }
111     $DB->delete_records('book_chapters', array('bookid'=>$book->id));
112     $DB->delete_records('book', array('id'=>$book->id));
114     return true;
117 /**
118  * Return use outline
119  *
120  * @param stdClass $course
121  * @param stdClass $user
122  * @param stdClass $mod
123  * @param object $book
124  * @return object|null
125  */
126 function book_user_outline($course, $user, $mod, $book) {
127     global $DB;
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;
139         return $result;
140     }
141     return NULL;
144 /**
145  * Print a detailed representation of what a  user has done with
146  * a given particular instance of this module, for user activity reports.
147  *
148  * @param stdClass $course
149  * @param stdClass $user
150  * @param stdClass $mod
151  * @param stdClass $book
152  * @return bool
153  */
154 function book_user_complete($course, $user, $mod, $book) {
155     return true;
158 /**
159  * Given a course and a time, this module should find recent activity
160  * that has occurred in book activities and print it out.
161  *
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
166  */
167 function book_print_recent_activity($course, $viewfullnames, $timestart) {
168     return false;  //  True if anything was printed, otherwise false
171 /**
172  * No cron in book.
173  *
174  * @return bool
175  */
176 function book_cron () {
177     return true;
180 /**
181  * No grading in book.
182  *
183  * @param int $bookid
184  * @return null
185  */
186 function book_grades($bookid) {
187     return null;
190 /**
191  * Returns the users with data in one book
192  *
193  * @todo deprecated - to be deleted in 2.2
194  * @param int $bookid
195  * @return array
196  */
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.
203     return false;
206 /**
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
210  * as reference.
211  *
212  * @param int $bookid
213  * @param int $scaleid
214  * @return boolean True if the scale is used by any journal
215  */
216 function book_scale_used($bookid,$scaleid) {
217     return false;
220 /**
221  * Checks if scale is being used by any instance of book
222  *
223  * This is used to find out if scale used anywhere
224  *
225  * @param int $scaleid
226  * @return bool true if the scale is used by any book
227  */
228 function book_scale_used_anywhere($scaleid) {
229     return false;
232 /**
233  * Return read actions.
234  * @return array
235  */
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");
245         }
246         $function = 'booktool_'.$plugin.'_get_view_actions';
247         if (function_exists($function)) {
248             if ($actions = $function()) {
249                 $return = array_merge($return, $actions);
250             }
251         }
252     }
254     return $return;
257 /**
258  * Return write actions.
259  * @return array
260  */
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");
270         }
271         $function = 'booktool_'.$plugin.'_get_post_actions';
272         if (function_exists($function)) {
273             if ($actions = $function()) {
274                 $return = array_merge($return, $actions);
275             }
276         }
277     }
279     return $return;
282 /**
283  * Supported features
284  *
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
287  */
288 function book_supports($feature) {
289     switch($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;
301     }
304 /**
305  * Adds module specific settings to the settings block
306  *
307  * @param settings_navigation $settingsnav The settings navigation object
308  * @param navigation_node $booknode The node to add module settings to
309  * @return void
310  */
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') {
315         return;
316     }
318     if (empty($PAGE->cm->context)) {
319         $PAGE->cm->context = get_context_instance(CONTEXT_MODULE, $PAGE->cm->instance);
320     }
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");
326         }
327         $function = 'booktool_'.$plugin.'_extend_settings_navigation';
328         if (function_exists($function)) {
329             $function($settingsnav, $booknode);
330         }
331     }
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");
338             $edit = '0';
339         } else {
340             $string = get_string("turneditingon");
341             $edit = '1';
342         }
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);
345     }
349 /**
350  * Lists all browsable file areas
351  * @param object $course
352  * @param object $cm
353  * @param object $context
354  * @return array
355  */
356 function book_get_file_areas($course, $cm, $context) {
357     $areas = array();
358     $areas['chapter'] = get_string('chapters', 'mod_book');
359     return $areas;
362 /**
363  * File browsing support for book module ontent area.
364  * @param object $browser
365  * @param object $areas
366  * @param object $course
367  * @param object $cm
368  * @param object $context
369  * @param string $filearea
370  * @param int $itemid
371  * @param string $filepath
372  * @param string $filename
373  * @return object file_info instance or null if not found
374  */
375 function book_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
376     global $CFG, $DB;
378     // note: 'intro' area is handled in file_browser automatically
380     if (!has_capability('mod/book:read', $context)) {
381         return null;
382     }
384     if ($filearea !== 'chapter') {
385         return null;
386     }
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);
392     }
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)) {
398         return null;
399     }
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);
411 /**
412  * Serves the book attachments. Implements needed access control ;-)
413  *
414  * @param object $course
415  * @param object $cm
416  * @param object $context
417  * @param string $filearea
418  * @param array $args
419  * @param bool $forcedownload
420  * @return bool false if file not found, does not return if found - just send the file
421  */
422 function book_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) {
423     global $DB;
425     if ($context->contextlevel != CONTEXT_MODULE) {
426         return false;
427     }
429     require_course_login($course, true, $cm);
431     if ($filearea !== 'chapter') {
432         return false;
433     }
435     if (!has_capability('mod/book:read', $context)) {
436         return false;
437     }
439     $chid = (int)array_shift($args);
441     if (!$book = $DB->get_record('book', array('id'=>$cm->instance))) {
442         return false;
443     }
445     if (!$chapter = $DB->get_record('book_chapters', array('id'=>$chid, 'bookid'=>$book->id))) {
446         return false;
447     }
449     if ($chapter->hidden and !has_capability('mod/book:viewhiddenchapters', $context)) {
450         return false;
451     }
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()) {
457         return false;
458     }
460     // finally send the file
461     send_stored_file($file, 360, 0, false);
464 /**
465  * Return a list of page types
466  *
467  * @param string $pagetype current page type
468  * @param stdClass $parentcontext Block's parent context
469  * @param stdClass $currentcontext Current context of block
470  * @return array
471  */
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;