Merge branch 'MDL-34573_accessibility' of git://github.com/rwijaya/moodle
[moodle.git] / mod / imscp / lib.php
blob4c4b31c9bacff6fce62e4db17806e283a979ab8e
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.
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 * Mandatory public API of imscp module
21 * @package mod
22 * @subpackage imscp
23 * @copyright 2009 Petr Skoda {@link http://skodak.org}
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 defined('MOODLE_INTERNAL') || die();
29 /**
30 * List of features supported in IMS CP module
31 * @param string $feature FEATURE_xx constant for requested feature
32 * @return mixed True if module supports feature, false if not, null if doesn't know
34 function imscp_supports($feature) {
35 switch($feature) {
36 case FEATURE_MOD_ARCHETYPE: return MOD_ARCHETYPE_RESOURCE;
37 case FEATURE_GROUPS: return false;
38 case FEATURE_GROUPINGS: return false;
39 case FEATURE_GROUPMEMBERSONLY: return true;
40 case FEATURE_MOD_INTRO: return true;
41 case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
42 case FEATURE_GRADE_HAS_GRADE: return false;
43 case FEATURE_GRADE_OUTCOMES: return false;
44 case FEATURE_BACKUP_MOODLE2: return true;
45 case FEATURE_SHOW_DESCRIPTION: return true;
47 default: return null;
51 /**
52 * Returns all other caps used in module
53 * @return array
55 function imscp_get_extra_capabilities() {
56 return array('moodle/site:accessallgroups');
59 /**
60 * This function is used by the reset_course_userdata function in moodlelib.
61 * @param $data the data submitted from the reset course.
62 * @return array status array
64 function imscp_reset_userdata($data) {
65 return array();
68 /**
69 * List of view style log actions
70 * @return array
72 function imscp_get_view_actions() {
73 return array('view', 'view all');
76 /**
77 * List of update style log actions
78 * @return array
80 function imscp_get_post_actions() {
81 return array('update', 'add');
84 /**
85 * Add imscp instance.
86 * @param object $data
87 * @param object $mform
88 * @return int new imscp instance id
90 function imscp_add_instance($data, $mform) {
91 global $CFG, $DB;
92 require_once("$CFG->dirroot/mod/imscp/locallib.php");
94 $cmid = $data->coursemodule;
96 $data->timemodified = time();
97 $data->revision = 1;
98 $data->structure = null;
100 $data->id = $DB->insert_record('imscp', $data);
102 // we need to use context now, so we need to make sure all needed info is already in db
103 $DB->set_field('course_modules', 'instance', $data->id, array('id'=>$cmid));
104 $context = context_module::instance($cmid);
105 $imscp = $DB->get_record('imscp', array('id'=>$data->id), '*', MUST_EXIST);
107 if ($filename = $mform->get_new_filename('package')) {
108 if ($package = $mform->save_stored_file('package', $context->id, 'mod_imscp', 'backup', 1, '/', $filename)) {
109 // extract package content
110 $packer = get_file_packer('application/zip');
111 $package->extract_to_storage($packer, $context->id, 'mod_imscp', 'content', 1, '/');
112 $structure = imscp_parse_structure($imscp, $context);
113 $imscp->structure = is_array($structure) ? serialize($structure) : null;
114 $DB->update_record('imscp', $imscp);
118 return $data->id;
122 * Update imscp instance.
123 * @param object $data
124 * @param object $mform
125 * @return bool true
127 function imscp_update_instance($data, $mform) {
128 global $CFG, $DB;
129 require_once("$CFG->dirroot/mod/imscp/locallib.php");
131 $cmid = $data->coursemodule;
133 $data->timemodified = time();
134 $data->id = $data->instance;
135 $data->structure = null; // better reparse structure after each update
137 $DB->update_record('imscp', $data);
139 $context = context_module::instance($cmid);
140 $imscp = $DB->get_record('imscp', array('id'=>$data->id), '*', MUST_EXIST);
142 if ($filename = $mform->get_new_filename('package')) {
143 $fs = get_file_storage();
145 $imscp->revision++;
146 $DB->update_record('imscp', $imscp);
148 // get a list of existing packages before adding new package
149 if ($imscp->keepold > -1) {
150 $packages = $fs->get_area_files($context->id, 'mod_imscp', 'backup', false, "itemid ASC", false);
151 } else {
152 $packages = array();
155 $package = $mform->save_stored_file('package', $context->id, 'mod_imscp', 'backup', $imscp->revision, '/', $filename);
157 // purge all extracted content
158 $fs->delete_area_files($context->id, 'mod_imscp', 'content');
160 // extract package content
161 if ($package) {
162 $packer = get_file_packer('application/zip');
163 $package->extract_to_storage($packer, $context->id, 'mod_imscp', 'content', $imscp->revision, '/');
166 // cleanup old package files, keep current + keepold
167 while ($packages and (count($packages) > $imscp->keepold)) {
168 $package = array_shift($packages);
169 $fs->delete_area_files($context->id, 'mod_imscp', 'backup', $package->get_itemid());
173 $structure = imscp_parse_structure($imscp, $context);
174 $imscp->structure = is_array($structure) ? serialize($structure) : null;
175 $DB->update_record('imscp', $imscp);
177 return true;
181 * Delete imscp instance.
182 * @param int $id
183 * @return bool true
185 function imscp_delete_instance($id) {
186 global $DB;
188 if (!$imscp = $DB->get_record('imscp', array('id'=>$id))) {
189 return false;
192 // note: all context files are deleted automatically
194 $DB->delete_records('imscp', array('id'=>$imscp->id));
196 return true;
200 * Return use outline
201 * @param object $course
202 * @param object $user
203 * @param object $mod
204 * @param object $imscp
205 * @return object|null
207 function imscp_user_outline($course, $user, $mod, $imscp) {
208 global $DB;
210 if ($logs = $DB->get_records('log', array('userid'=>$user->id, 'module'=>'imscp',
211 'action'=>'view', 'info'=>$imscp->id), 'time ASC')) {
213 $numviews = count($logs);
214 $lastlog = array_pop($logs);
216 $result = new stdClass();
217 $result->info = get_string('numviews', '', $numviews);
218 $result->time = $lastlog->time;
220 return $result;
222 return NULL;
226 * Return use complete
227 * @param object $course
228 * @param object $user
229 * @param object $mod
230 * @param object $imscp
232 function imscp_user_complete($course, $user, $mod, $imscp) {
233 global $CFG, $DB;
235 if ($logs = $DB->get_records('log', array('userid'=>$user->id, 'module'=>'imscp',
236 'action'=>'view', 'info'=>$imscp->id), 'time ASC')) {
237 $numviews = count($logs);
238 $lastlog = array_pop($logs);
240 $strmostrecently = get_string('mostrecently');
241 $strnumviews = get_string('numviews', '', $numviews);
243 echo "$strnumviews - $strmostrecently ".userdate($lastlog->time);
245 } else {
246 print_string('neverseen', 'imscp');
251 * Lists all browsable file areas
253 * @package mod_imscp
254 * @category files
255 * @param stdClass $course course object
256 * @param stdClass $cm course module object
257 * @param stdClass $context context object
258 * @return array
260 function imscp_get_file_areas($course, $cm, $context) {
261 $areas = array();
263 $areas['content'] = get_string('areacontent', 'imscp');
264 $areas['backup'] = get_string('areabackup', 'imscp');
266 return $areas;
270 * File browsing support for imscp module ontent area.
272 * @package mod_imscp
273 * @category files
274 * @param stdClass $browser file browser
275 * @param stdClass $areas file areas
276 * @param stdClass $course course object
277 * @param stdClass $cm course module object
278 * @param stdClass $context context object
279 * @param string $filearea file area
280 * @param int $itemid item ID
281 * @param string $filepath file path
282 * @param string $filename file name
283 * @return file_info instance or null if not found
285 function imscp_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
286 global $CFG, $DB;
288 // note: imscp_intro handled in file_browser automatically
290 if (!has_capability('moodle/course:managefiles', $context)) {
291 // no peaking here for students!!
292 return null;
295 if ($filearea !== 'content' and $filearea !== 'backup') {
296 return null;
299 require_once("$CFG->dirroot/mod/imscp/locallib.php");
301 if (is_null($itemid)) {
302 return new imscp_file_info($browser, $course, $cm, $context, $areas, $filearea, $itemid);
305 $fs = get_file_storage();
306 $filepath = is_null($filepath) ? '/' : $filepath;
307 $filename = is_null($filename) ? '.' : $filename;
308 if (!$storedfile = $fs->get_file($context->id, 'mod_imscp', $filearea, $itemid, $filepath, $filename)) {
309 return null;
312 // do not allow manual modification of any files!
313 $urlbase = $CFG->wwwroot.'/pluginfile.php';
314 return new file_info_stored($browser, $context, $storedfile, $urlbase, $itemid, true, true, false, false); //no writing here!
318 * Serves the imscp files.
320 * @package mod_imscp
321 * @category files
322 * @param stdClass $course course object
323 * @param stdClass $cm course module object
324 * @param stdClass $context context object
325 * @param string $filearea file area
326 * @param array $args extra arguments
327 * @param bool $forcedownload whether or not force download
328 * @param array $options additional options affecting the file serving
329 * @return bool false if file not found, does not return if found - justsend the file
331 function imscp_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) {
332 global $CFG, $DB;
334 if ($context->contextlevel != CONTEXT_MODULE) {
335 return false;
338 require_login($course, true, $cm);
340 if ($filearea === 'content') {
341 if (!has_capability('mod/imscp:view', $context)) {
342 return false;
344 $revision = array_shift($args);
345 $fs = get_file_storage();
346 $relativepath = implode('/', $args);
347 if ($relativepath === 'imsmanifest.xml') {
348 if (!has_capability('moodle/course:managefiles', $context)) {
349 // no stealing of detailed package info ;-)
350 return false;
353 $fullpath = "/$context->id/mod_imscp/$filearea/$revision/$relativepath";
354 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
355 return false;
358 // finally send the file
359 send_stored_file($file, 86400, 0, $forcedownload, $options);
361 } else if ($filearea === 'backup') {
362 if (!has_capability('moodle/course:managefiles', $context)) {
363 // no stealing of package backups
364 return false;
366 $revision = array_shift($args);
367 $fs = get_file_storage();
368 $relativepath = implode('/', $args);
369 $fullpath = "/$context->id/mod_imscp/$filearea/$revision/$relativepath";
370 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
371 return false;
374 // finally send the file
375 send_stored_file($file, 86400, 0, $forcedownload, $options);
377 } else {
378 return false;
383 * Return a list of page types
384 * @param string $pagetype current page type
385 * @param stdClass $parentcontext Block's parent context
386 * @param stdClass $currentcontext Current context of block
388 function imscp_page_type_list($pagetype, $parentcontext, $currentcontext) {
389 $module_pagetype = array('mod-imscp-*'=>get_string('page-mod-imscp-x', 'imscp'));
390 return $module_pagetype;