. /** * The Web service script that is called from the filepicker front end * * @since 2.0 * @package repository * @copyright 2009 Dongsheng Cai {@link http://dongsheng.org} * @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_array('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); $usefilereference = optional_param('usefilereference', '', 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 @header('Content-type: text/html; charset=utf-8'); // If uploaded file is larger than post_max_size (php.ini) setting, $_POST content will be empty. if (empty($_POST) && !empty($action)) { $err->error = get_string('errorpostmaxsize', 'repository'); die(json_encode($err)); } if (!confirm_sesskey()) { $err->error = get_string('invalidsesskey', 'error'); 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; $repooptions = array( 'ajax' => true, 'name' => $repository->name, 'type' => $type, 'mimetypes' => $accepted_types ); $repo = new $classname($repo_id, $contextid, $repooptions); } 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['issearchresult'] = 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 $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['file'] = $saveas_filename; $info['type'] = 'link'; $info['url'] = $link; echo json_encode($info); die; } else { $fs = get_file_storage(); // Some repository plugins are hosting moodle internal files, we cannot use get_file // method, so we use copy_to_area method // (local, user, coursefiles, recent) if ($repo->has_moodle_files() && ($usefilereference != 'yes')) { // check filesize against max allowed size $filesize = $repo->get_file_size($source); if (empty($filesize)) { $filesize = 0; } if (($maxbytes !== -1) && ($filesize > $maxbytes)) { throw new file_exception('maxbytes'); } // If the moodle file is an alias to a file in external repository // we copy this alias instead of create alias to alias // {@link repository::copy_to_area()}. $fileinfo = $repo->copy_to_area($source, $itemid, $saveas_path, $saveas_filename); if (!isset($fileinfo['event'])) { $fileinfo['file'] = $fileinfo['title']; } echo json_encode($fileinfo); die; } // Prepare file record. $record = new stdClass(); $record->filepath = $saveas_path; $record->filename = $saveas_filename; $record->component = 'user'; $record->filearea = 'draft'; if (!is_numeric($itemid)) { $record->itemid = 0; } else { $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; } if ($record->filepath !== '/') { $record->filepath = trim($record->filepath, '/'); $record->filepath = '/'.$record->filepath.'/'; } $usercontext = get_context_instance(CONTEXT_USER, $USER->id); $now = time(); $record->contextid = $usercontext->id; $record->timecreated = $now; $record->timemodified = $now; $record->userid = $USER->id; $record->mimetype = mimeinfo('type', $record->filename); if ($usefilereference == 'yes') { $reference = $repo->get_file_reference($source); // get reference life time from repo $record->referencelifetime = $repo->get_reference_file_lifetime($reference); // Check if file exists. if (repository::draftfile_exists($itemid, $saveas_path, $saveas_filename)) { // File name being used, rename it. $unused_filename = repository::get_unused_filename($itemid, $saveas_path, $saveas_filename); $record->filename = $unused_filename; // Create a file copy using unused filename. $storedfile = $fs->create_file_from_reference($record, $repo_id, $reference); $event = array(); $event['event'] = 'fileexists'; $event['newfile'] = new stdClass; $event['newfile']->filepath = $saveas_path; $event['newfile']->filename = $unused_filename; $event['newfile']->url = moodle_url::make_draftfile_url($itemid, $saveas_path, $unused_filename)->out(); $event['existingfile'] = new stdClass; $event['existingfile']->filepath = $saveas_path; $event['existingfile']->filename = $saveas_filename; $event['existingfile']->url = moodle_url::make_draftfile_url($itemid, $saveas_path, $saveas_filename)->out();; echo json_encode($event); die; } $storedfile = $fs->create_file_from_reference($record, $repo_id, $reference); // Repository plugin callback // You can cache reository file in this callback // or complete other tasks. $repo->cache_file_by_reference($reference, $storedfile); $info = array( 'url'=>moodle_url::make_draftfile_url($storedfile->get_itemid(), $storedfile->get_filepath(), $storedfile->get_filename())->out(), 'id'=>$storedfile->get_itemid(), 'file'=>$storedfile->get_filename(), 'icon' => $OUTPUT->pix_url(file_extension_icon($storedfile->get_filename(), 32))->out(), ); echo json_encode($info); die; } else { // Download file to moodle. $downloadedfile = $repo->get_file($source, $saveas_filename); if ($downloadedfile['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->source = !empty($downloadedfile['url']) ? $downloadedfile['url'] : ''; $info = repository::move_to_filepool($downloadedfile['path'], $record); if (empty($info)) { $info['e'] = get_string('error', 'moodle'); } } echo json_encode($info); die; } break; case 'upload': $result = $repo->upload($saveas_filename, $maxbytes); echo json_encode($result); break; case 'overwrite': // existing file $filepath = required_param('existingfilepath', PARAM_PATH); $filename = required_param('existingfilename', PARAM_FILE); // user added file which needs to replace the existing file $newfilepath = required_param('newfilepath', PARAM_PATH); $newfilename = required_param('newfilename', PARAM_FILE); $info = repository::overwrite_existing_draftfile($itemid, $filepath, $filename, $newfilepath, $newfilename); echo json_encode($info); break; case 'deletetmpfile': // delete tmp file $newfilepath = required_param('newfilepath', PARAM_PATH); $newfilename = required_param('newfilename', PARAM_FILE); echo json_encode(repository::delete_tempfile_from_draft($itemid, $newfilepath, $newfilename)); break; }