MDL-20068 new Page module, includes migrate from old mod/resource; remaining issues...
[moodle.git] / mod / page / lib.php
1 <?php
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/>.
18 /**
19  * @package   mod-page
20  * @copyright 2009 Petr Skoda (http://skodak.org)
21  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22  */
24 /**
25  * List of features supported in Page module
26  * @param string $feature FEATURE_xx constant for requested feature
27  * @return mixed True if module supports feature, false if not, null if doesn't know
28  */
29 function page_supports($feature) {
30     switch($feature) {
31         case FEATURE_MOD_ARCHETYPE:           return MOD_ARCHETYPE_RESOURCE;
32         case FEATURE_GROUPS:                  return false;
33         case FEATURE_GROUPINGS:               return false;
34         case FEATURE_GROUPMEMBERSONLY:        return true;
35         case FEATURE_MOD_INTRO:               return true;
36         case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
37         case FEATURE_GRADE_HAS_GRADE:         return false;
38         case FEATURE_GRADE_OUTCOMES:          return false;
40         default: return null;
41     }
42 }
44 /**
45  * Returns all other caps used in module
46  * @return array
47  */
48 function page_get_extra_capabilities() {
49     return array('moodle/site:accessallgroups');
50 }
52 /**
53  * This function is used by the reset_course_userdata function in moodlelib.
54  * @param $data the data submitted from the reset course.
55  * @return array status array
56  */
57 function page_reset_userdata($data) {
58     return array();
59 }
61 /**
62  * List of view style log actions
63  * @return array
64  */
65 function page_get_view_actions() {
66     return array('view','view all');
67 }
69 /**
70  * List of update style log actions
71  * @return array
72  */
73 function page_get_post_actions() {
74     return array('update', 'add');
75 }
77 /**
78  * Add page instance.
79  * @param object $data
80  * @param object $mform
81  * @return int new resoruce instance id
82  */
83 function page_add_instance($data, $mform) {
84     global $CFG, $DB;
85     require_once("$CFG->libdir/resourcelib.php");
87     $cmid        = $data->coursemodule;
88     $draftitemid = $data->page['itemid'];
90     $data->timemodified = time();
91     $displayoptions = array();
92     if ($data->display == RESOURCELIB_DISPLAY_POPUP) {
93         $displayoptions['popupwidth']  = $data->popupwidth;
94         $displayoptions['popupheight'] = $data->popupheight;
95     }
96     $displayoptions['printheading'] = $data->printheading;
97     $displayoptions['printintro']   = $data->printintro;
98     $data->displayoptions = serialize($displayoptions);
100     $data->content       = $data->page['text'];
101     $data->contentformat = $data->page['format'];
103     $data->id = $DB->insert_record('page', $data);
105     // we need to use context now, so we need to make sure all needed info is already in db
106     $DB->set_field('course_modules', 'instance', $data->id, array('id'=>$cmid));
107     $context = get_context_instance(CONTEXT_MODULE, $cmid);
109     if ($draftitemid) {
110         $data->content = file_save_draft_area_files($draftitemid, $context->id, 'page_content', 0, page_get_editor_options($context), $data->content);
111         $DB->update_record('page', $data);
112     }
114     return $data->id;
117 /**
118  * Update page instance.
119  * @param object $data
120  * @param object $mform
121  * @return bool true
122  */
123 function page_update_instance($data, $mform) {
124     global $CFG, $DB;
125     require_once("$CFG->libdir/resourcelib.php");
127     $cmid        = $data->coursemodule;
128     $draftitemid = $data->page['itemid'];
130     $data->timemodified = time();
131     $data->id           = $data->instance;
132     $data->revision++;
134     $displayoptions = array();
135     if ($data->display == RESOURCELIB_DISPLAY_POPUP) {
136         $displayoptions['popupwidth']  = $data->popupwidth;
137         $displayoptions['popupheight'] = $data->popupheight;
138     }
139     $displayoptions['printheading'] = $data->printheading;
140     $displayoptions['printintro']   = $data->printintro;
141     $data->displayoptions = serialize($displayoptions);
143     $data->content       = $data->page['text'];
144     $data->contentformat = $data->page['format'];
146     $DB->update_record('page', $data);
148     $context = get_context_instance(CONTEXT_MODULE, $cmid);
149     if ($draftitemid) {
150         $data->content = file_save_draft_area_files($draftitemid, $context->id, 'page_content', 0, page_get_editor_options($context), $data->content);
151         $DB->update_record('page', $data);
152     }
154     return true;
157 /**
158  * Delete page instance.
159  * @param int $id
160  * @return bool true
161  */
162 function page_delete_instance($id) {
163     global $DB;
165     if (!$page = $DB->get_record('page', array('id'=>$id))) {
166         return false;
167     }
169     // note: all context files are deleted automatically
171     $DB->delete_records('page', array('id'=>$page->id));
173     return true;
176 /**
177  * Return use outline
178  * @param object $course
179  * @param object $user
180  * @param object $mod
181  * @param object $page
182  * @return object|null
183  */
184 function page_user_outline($course, $user, $mod, $page) {
185     global $DB;
187     if ($logs = $DB->get_records('log', array('userid'=>$user->id, 'module'=>'page',
188                                               'action'=>'view', 'info'=>$page->id), 'time ASC')) {
190         $numviews = count($logs);
191         $lastlog = array_pop($logs);
193         $result = new object();
194         $result->info = get_string('numviews', '', $numviews);
195         $result->time = $lastlog->time;
197         return $result;
198     }
199     return NULL;
202 /**
203  * Return use complete
204  * @param object $course
205  * @param object $user
206  * @param object $mod
207  * @param object $page
208  */
209 function page_user_complete($course, $user, $mod, $page) {
210     global $CFG, $DB;
212     if ($logs = $DB->get_records('log', array('userid'=>$user->id, 'module'=>'page',
213                                               'action'=>'view', 'info'=>$page->id), 'time ASC')) {
214         $numviews = count($logs);
215         $lastlog = array_pop($logs);
217         $strmostrecently = get_string('mostrecently');
218         $strnumviews = get_string('numviews', '', $numviews);
220         echo "$strnumviews - $strmostrecently ".userdate($lastlog->time);
222     } else {
223         print_string('neverseen', 'page');
224     }
227 /**
228  * Returns the users with data in one page
229  *
230  * @param int $pageid
231  * @return bool false
232  */
233 function page_get_participants($pageid) {
234     return false;
237 /**
238  * Given a course_module object, this function returns any
239  * "extra" information that may be needed when printing
240  * this activity in a course listing.
241  *
242  * See {@link get_array_of_activities()} in course/lib.php
243  *
244  * @param object $coursemodule
245  * @return object info
246  */
247 function page_get_coursemodule_info($coursemodule) {
248     global $CFG, $DB;
249     require_once("$CFG->libdir/resourcelib.php");
251     if (!$page = $DB->get_record('page', array('id'=>$coursemodule->instance), 'id, name, display, displayoptions')) {
252         return NULL;
253     }
255     if ($page->display != RESOURCELIB_DISPLAY_POPUP) {
256         return null;
257     }
259     $info = new object();
260     $info->name = $page->name;
262     $fullurl = "$CFG->wwwroot/mod/page/view.php?id=$coursemodule->id&amp;inpopup=1";
263     $options = empty($page->displayoptions) ? array() : unserialize($page->displayoptions);
264     $width  = empty($options['popupwidth'])  ? 620 : $options['popupwidth'];
265     $height = empty($options['popupheight']) ? 450 : $options['popupheight'];
266     $wh = "width=$width,height=$height,toolbar=no,location=no,menubar=no,copyhistory=no,status=no,directories=no,scrollbars=yes,resizable=yes";
267     $info->extra = urlencode("onclick=\"window.open('$fullurl', '', '$wh'); return false;\"");
269     return $info;
273 /**
274  * Lists all browsable file areas
275  * @param object $course
276  * @param object $cm
277  * @param object $context
278  * @return array
279  */
280 function page_get_file_areas($course, $cm, $context) {
281     $areas = array();
282     if (has_capability('moodle/course:managefiles', $context)) {
283         $areas['page_content'] = get_string('pagecontent', 'page');
284     }
285     return $areas;
288 /**
289  * File browsing support for page module ontent area.
290  * @param object $browser
291  * @param object $areas
292  * @param object $course
293  * @param object $cm
294  * @param object $context
295  * @param string $filearea
296  * @param int $itemid
297  * @param string $filepath
298  * @param string $filename
299  * @return object file_info instance or null if not found
300  */
301 function page_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
302     global $CFG;
304     $canwrite = has_capability('moodle/course:managefiles', $context);
306     $fs = get_file_storage();
308     if ($filearea === 'page_content') {
309         $filepath = is_null($filepath) ? '/' : $filepath;
310         $filename = is_null($filename) ? '.' : $filename;
312         $urlbase = $CFG->wwwroot.'/pluginfile.php';
313         if (!$storedfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) {
314             if ($filepath === '/' and $filename === '.') {
315                 $storedfile = new virtual_root_file($context->id, $filearea, 0);
316             } else {
317                 // not found
318                 return null;
319             }
320         }
321         require_once("$CFG->dirroot/mod/page/locallib.php");
322         return new page_content_file_info($browser, $context, $storedfile, $urlbase, $areas[$filearea], true, true, $canwrite, false);
323     }
325     // note: page_intro handled in file_browser automatically
327     return null;
330 /**
331  * Serves the page files.
332  * @param object $course
333  * @param object $cminfo
334  * @param object $context
335  * @param string $filearea
336  * @param array $args
337  * @param bool $forcedownload
338  * @return bool false if file not found, does not return if found - justsend the file
339  */
340 function page_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) {
341     global $CFG, $DB;
342     require_once("$CFG->libdir/resourcelib.php");
344     if (!$cminfo->uservisible) {
345         return false;
346     }
348     if ($filearea !== 'page_content') {
349         // intro is handled automatically in pluginfile.php
350         return false;
351     }
353     if (!$cm = get_coursemodule_from_instance('page', $cminfo->instance, $course->id)) {
354         return false;
355     }
357     require_course_login($course, true, $cm);
359     array_shift($args); // ignore revision - designed to prevent caching problems only
361     $fs = get_file_storage();
362     $relativepath = '/'.implode('/', $args);
363     $fullpath = $context->id.$filearea.'0'.$relativepath;
364     if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
365         $page = $DB->get_record('page', array('id'=>$cminfo->instance), 'id, legacyfiles', MUST_EXIST);
366         if ($page->legacyfiles != RESOURCELIB_LEGACYFILES_ACTIVE) {
367             return false;
368         }
369         require_once("$CFG->dirroot/mod/resource/db/upgradelib.php");
370         if (!$file = resource_try_file_migration($relativepath, $cminfo->id, $cminfo->course, 'page_content', 0)) {
371             return false;
372         }
373         //file migrate - update flag
374         $page->legacyfileslast = time();
375         $DB->update_record('page', $page);
376     }
378     // finally send the file
379     send_stored_file($file, 86400, 0, $forcedownload);