. /** * The Web service script that is called from the filepicker front end * * @since 2.0 * @package moodlecore * @subpackage repository * @copyright 2009 Dongsheng Cai * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ define('AJAX_SCRIPT', true); require_once(dirname(dirname(__FILE__)).'/config.php'); require_once(dirname(dirname(__FILE__)).'/lib/filelib.php'); require_once(dirname(__FILE__).'/lib.php'); $err = new stdclass; /// Parameters $action = optional_param('action', '', PARAM_ALPHA); $repo_id = optional_param('repo_id', 0, PARAM_INT); // Repository ID $contextid = optional_param('ctx_id', SYSCONTEXTID, PARAM_INT); // Context ID $env = optional_param('env', 'filepicker', PARAM_ALPHA); // Opened in editor or moodleform $license = optional_param('license', $CFG->sitedefaultlicense, PARAM_TEXT); $author = optional_param('author', '', PARAM_TEXT); // File author $source = optional_param('source', '', PARAM_RAW); // File to download $itemid = optional_param('itemid', 0, PARAM_INT); // Itemid $page = optional_param('page', '', PARAM_RAW); // Page $maxbytes = optional_param('maxbytes', 0, PARAM_INT); // Maxbytes $req_path = optional_param('p', '', PARAM_RAW); // Path $accepted_types = optional_param('accepted_types', '*', PARAM_RAW); $saveas_filename = optional_param('title', '', PARAM_FILE); // save as file name $saveas_path = optional_param('savepath', '/', PARAM_PATH); // save as file path $search_text = optional_param('s', '', PARAM_CLEANHTML); $linkexternal = optional_param('linkexternal', '', PARAM_ALPHA); list($context, $course, $cm) = get_context_info_array($contextid); require_login($course, false, $cm); $PAGE->set_context($context); echo $OUTPUT->header(); // send headers if (!confirm_sesskey()) { $err->error = get_string('invalidsesskey'); die(json_encode($err)); } /// Get repository instance information $sql = 'SELECT i.name, i.typeid, r.type FROM {repository} r, {repository_instances} i WHERE i.id=? AND i.typeid=r.id'; if (!$repository = $DB->get_record_sql($sql, array($repo_id))) { $err->error = get_string('invalidrepositoryid', 'repository'); die(json_encode($err)); } else { $type = $repository->type; } /// Check permissions repository::check_capability($contextid, $repository); $moodle_maxbytes = get_max_upload_file_size(); // to prevent maxbytes greater than moodle maxbytes setting if ($maxbytes == 0 || $maxbytes>=$moodle_maxbytes) { $maxbytes = $moodle_maxbytes; } /// Wait as long as it takes for this script to finish set_time_limit(0); // Early actions which need to be done before repository instances initialised switch ($action) { // global search case 'gsearch': $params = array(); $params['context'] = array(get_context_instance_by_id($contextid), get_system_context()); $params['currentcontext'] = get_context_instance_by_id($contextid); $repos = repository::get_instances($params); $list = array(); foreach($repos as $repo){ if ($repo->global_search()) { $ret = $repo->search($search_text); array_walk($ret['list'], 'repository_attach_id', $repo->id); // See function below $tmp = array_merge($list, $ret['list']); $list = $tmp; } } $listing = array('list'=>$list); $listing['gsearch'] = true; die(json_encode($listing)); break; // remove the cache files & logout case 'ccache': $cache = new curl_cache; $cache->refresh(); $action = 'list'; break; } if (file_exists($CFG->dirroot.'/repository/'.$type.'/lib.php')) { require_once($CFG->dirroot.'/repository/'.$type.'/lib.php'); $classname = 'repository_' . $type; $repo = new $classname($repo_id, $contextid, array('ajax'=>true, 'name'=>$repository->name, 'type'=>$type)); } else { $err->error = get_string('invalidplugin', 'repository', $type); die(json_encode($err)); } /// These actions all occur on the currently active repository instance switch ($action) { case 'sign': case 'signin': case 'list': if ($repo->check_login()) { $listing = $repo->get_listing($req_path, $page); $listing['repo_id'] = $repo_id; echo json_encode($listing); break; } else { $action = 'login'; } case 'login': $listing = $repo->print_login(); $listing['repo_id'] = $repo_id; echo json_encode($listing); break; case 'logout': $logout = $repo->logout(); $logout['repo_id'] = $repo_id; echo json_encode($logout); break; case 'searchform': $search_form['form'] = $repo->print_search(); echo json_encode($search_form); break; case 'search': $search_result = $repo->search($search_text, (int)$page); $search_result['repo_id'] = $repo_id; $search_result['search_result'] = true; echo json_encode($search_result); break; case 'download': // validate mimetype $mimetypes = array(); if ((is_array($accepted_types) and in_array('*', $accepted_types)) or $accepted_types == '*') { $mimetypes = '*'; } else { foreach ($accepted_types as $type) { $mimetypes[] = mimeinfo('type', $type); } if (!in_array(mimeinfo('type', $saveas_filename), $mimetypes)) { throw new moodle_exception('invalidfiletype', 'repository', '', get_string(mimeinfo('type', $saveas_filename), 'mimetypes')); } } // We have two special repository type need to deal with // local and recent plugins don't added new files to moodle, just add new records to database // so we don't check user quota and maxbytes here if (in_array($repo->options['type'], array('local', 'recent', 'user'))) { $fileinfo = $repo->copy_to_area($source, $itemid, $saveas_path, $saveas_filename); $info = array(); $info['file'] = $fileinfo['title']; $info['id'] = $itemid; $info['url'] = $CFG->httpswwwroot.'/draftfile.php/'.$fileinfo['contextid'].'/user/draft/'.$itemid.'/'.$fileinfo['title']; $filesize = $fileinfo['filesize']; if (($maxbytes!==-1) && ($filesize>$maxbytes)) { throw new file_exception('maxbytes'); } echo json_encode($info); die; // ends here!! } else { $allowexternallink = (int)get_config(null, 'repositoryallowexternallinks'); if (!empty($allowexternallink)) { $allowexternallink = true; } else { $allowexternallink = false; } // allow external links in url element all the time $allowexternallink = ($allowexternallink || ($env == 'url')); // Use link of the files if ($allowexternallink and $linkexternal === 'yes' and ($repo->supported_returntypes() & FILE_EXTERNAL)) { // use external link $link = $repo->get_link($source); $info = array(); $info['filename'] = $saveas_filename; $info['type'] = 'link'; $info['url'] = $link; echo json_encode($info); die; } else { // Download file to moodle $file = $repo->get_file($source, $saveas_filename); if ($file['path'] === false) { $err->error = get_string('cannotdownload', 'repository'); die(json_encode($err)); } // check if exceed maxbytes if (($maxbytes!==-1) && (filesize($file['path']) > $maxbytes)) { throw new file_exception('maxbytes'); } $record = new stdclass; $record->filepath = $saveas_path; $record->filename = $saveas_filename; $record->component = 'user'; $record->filearea = 'draft'; $record->itemid = $itemid; if (!empty($file['license'])) { $record->license = $file['license']; } else { $record->license = $license; } if (!empty($file['author'])) { $record->author = $file['author']; } else { $record->author = $author; } $record->source = !empty($file['url']) ? $file['url'] : ''; $info = repository::move_to_filepool($file['path'], $record); if (empty($info)) { $info['e'] = get_string('error', 'moodle'); } echo json_encode($info); die; } } break; case 'upload': // handle exception here instead moodle default exception handler // see MDL-23407 try { // TODO: add file scanning MDL-19380 into each plugin $result = $repo->upload(); echo json_encode($result); } catch (Exception $e) { $err->error = $e->getMessage(); echo json_encode($err); die; } break; } /** * Small function to walk an array to attach repository ID * @param array $value * @param string $key * @param int $id */ function repository_attach_id(&$value, $key, $id){ $value['repo_id'] = $id; }