From 56e7d14f26b476ae6fb7e8bfba61052dca711ad6 Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Tue, 31 Jul 2012 10:17:07 +0800 Subject: [PATCH] MDL-34290 repository API: do not confuse source and reference make sure that repository function get_file_source_info receives as argument the source of the file, and get_file receives a reference; reference is a value of DB field files_reference.reference and result of get_file_reference(source). Fix dropbox as the only repository that have different values in those fields; also added information about user in dropbox reference and original --- repository/dropbox/lib.php | 49 +++++++++++++++++++++------------- repository/filepicker.php | 17 +++++++----- repository/lib.php | 20 +++++++++----- repository/repository_ajax.php | 19 +++++++------ 4 files changed, 66 insertions(+), 39 deletions(-) diff --git a/repository/dropbox/lib.php b/repository/dropbox/lib.php index 186e63b59c1..9d73e3558b1 100644 --- a/repository/dropbox/lib.php +++ b/repository/dropbox/lib.php @@ -281,15 +281,22 @@ class repository_dropbox extends repository { } /** + * Downloads a file from external repository and saves it in temp dir * - * @param string $photo_id - * @param string $file - * @return string + * @throws moodle_exception when file could not be downloaded + * + * @param string $reference the content of files.reference field + * @param string $filename filename (without path) to save the downloaded file in the + * temporary directory, if omitted or file already exists the new filename will be generated + * @return array with elements: + * path: internal location of the file + * url: URL to the source (from parameters) */ - public function get_file($filepath, $saveas = '') { - $this->dropbox->set_access_token($this->access_key, $this->access_secret); + public function get_file($reference, $saveas = '') { + $reference = unserialize($reference); + $this->dropbox->set_access_token($reference->access_key, $reference->access_secret); $saveas = $this->prepare_file($saveas); - return $this->dropbox->get_file($filepath, $saveas); + return $this->dropbox->get_file($reference->path, $saveas); } /** * Add Plugin settings input to Moodle form @@ -354,10 +361,13 @@ class repository_dropbox extends repository { * @return string file referece */ public function get_file_reference($source) { + global $USER; $reference = new stdClass; $reference->path = $source; $reference->access_key = get_user_preferences($this->setting.'_access_key', ''); $reference->access_secret = get_user_preferences($this->setting.'_access_secret', ''); + $reference->userid = $USER->id; + $reference->username = fullname($USER); return serialize($reference); } @@ -380,13 +390,13 @@ class repository_dropbox extends repository { $this->set_access_secret($reference->access_secret); $path = $this->get_file($reference->path); $cachedfilepath = cache_file::create_from_file($reference, $path['path']); - } + } if ($cachedfilepath && is_readable($cachedfilepath)) { return (object)array('filepath' => $cachedfilepath); } else { return null; } - } + } /** * Get file from external repository by reference @@ -399,8 +409,8 @@ class repository_dropbox extends repository { */ public function cache_file_by_reference($reference, $storedfile) { $reference = unserialize($reference); - $path = $this->get_file($reference->path); - cache_file::create_from_file($reference, $path['path']); + $path = $this->get_file($reference); + cache_file::create_from_file($reference->path, $path['path']); } /** @@ -412,8 +422,12 @@ class repository_dropbox extends repository { * @return string */ public function get_reference_details($reference, $filestatus = 0) { + global $USER; $ref = unserialize($reference); $details = $this->get_name(); + if (isset($ref->userid) && $ref->userid != $USER->id && isset($ref->username)) { + $details .= ' ('.$ref->username.')'; + } if (isset($ref->path)) { $details .= ': '. $ref->path; } @@ -428,11 +442,12 @@ class repository_dropbox extends repository { /** * Return the source information * - * @param stdClass $filepath - * @return string|null + * @param string $source + * @return string */ - public function get_file_source_info($filepath) { - return 'Dropbox: ' . $filepath; + public function get_file_source_info($source) { + global $USER; + return 'Dropbox ('.fullname($USER).'): ' . $source; } /** @@ -471,10 +486,8 @@ class repository_dropbox extends repository { $cachedfile = cache_file::get($reference); if ($cachedfile === false) { // Re-fetch resource. - $this->set_access_key($reference->access_key); - $this->set_access_secret($reference->access_secret); - $path = $this->get_file($reference->path); - cache_file::create_from_file($reference, $path['path']); + $path = $this->get_file($reference); + cache_file::create_from_file($reference->path, $path['path']); } } } diff --git a/repository/filepicker.php b/repository/filepicker.php index fd16e6676ca..1b673318b1a 100644 --- a/repository/filepicker.php +++ b/repository/filepicker.php @@ -282,6 +282,11 @@ case 'download': if (!$repo->file_is_accessible($fileurl)) { print_error('storedfilecannotread'); } + $record = new stdClass(); + $reference = $repo->get_file_reference($fileurl); + + $sourcefield = $repo->get_file_source_info($fileurl); + $record->source = repository::build_source_field($sourcefield); // If file is already a reference, set $fileurl = file source, $repo = file repository // note that in this case user may not have permission to access the source file directly @@ -289,13 +294,14 @@ case 'download': if ($repo->has_moodle_files()) { $file = repository::get_moodle_file($fileurl); if ($file && $file->is_external_file()) { - $fileurl = $file->get_reference(); + $sourcefield = $file->get_source(); // remember the original source + $record->source = $repo::build_source_field($sourcefield); + $reference = $file->get_reference(); $repo_id = $file->get_repository_id(); $repo = repository::get_repository_by_id($repo_id, $contextid, $repooptions); } } - $record = new stdClass(); $record->filepath = $savepath; $record->filename = $filename; $record->component = 'user'; @@ -311,14 +317,11 @@ case 'download': $record->contextid = $user_context->id; $record->sortorder = 0; - $sourcefield = $repo->get_file_source_info($fileurl); - $record->source = repository::build_source_field($sourcefield); - if ($repo->has_moodle_files()) { - $fileinfo = $repo->copy_to_area($fileurl, $record, $maxbytes); + $fileinfo = $repo->copy_to_area($reference, $record, $maxbytes); redirect($home_url, get_string('downloadsucc', 'repository')); } else { - $thefile = $repo->get_file($fileurl, $filename); + $thefile = $repo->get_file($reference, $filename); if (!empty($thefile['path'])) { $filesize = filesize($thefile['path']); if ($maxbytes != -1 && $filesize>$maxbytes) { diff --git a/repository/lib.php b/repository/lib.php index 404e597ba54..bdf3d0d7b3e 100644 --- a/repository/lib.php +++ b/repository/lib.php @@ -1164,9 +1164,8 @@ abstract class repository { /** * Return human readable reference information - * {@link stored_file::get_reference()} * - * @param string $reference + * @param string $reference value of DB field files_reference.reference * @param int $filestatus status of the file, 0 - ok, 666 - source missing * @return string */ @@ -1258,14 +1257,23 @@ abstract class repository { /** * Return the source information * - * @param stdClass $url + * The result of the function is stored in files.source field. It may be analysed + * when the source file is lost or repository may use it to display human-readable + * location of reference original. + * + * This method is called when file is picked for the first time only. When file + * (either copy or a reference) is already in moodle and it is being picked + * again to another file area (also as a copy or as a reference), the value of + * files.source is copied. + * + * @param string $source the value that repository returned in listing as 'source' * @return string|null */ - public function get_file_source_info($url) { + public function get_file_source_info($source) { if ($this->has_moodle_files()) { - return $this->get_reference_details($url, 0); + return $this->get_reference_details($source, 0); } - return $url; + return $source; } /** diff --git a/repository/repository_ajax.php b/repository/repository_ajax.php index 98701a581ac..14f16d5dba9 100644 --- a/repository/repository_ajax.php +++ b/repository/repository_ajax.php @@ -220,24 +220,27 @@ switch ($action) { throw new file_exception('storedfilecannotread'); } + // {@link repository::build_source_field()} + $sourcefield = $repo->get_file_source_info($source); + $record->source = $repo::build_source_field($sourcefield); + + $reference = $repo->get_file_reference($source); + // If file is already a reference, set $source = file source, $repo = file repository // note that in this case user may not have permission to access the source file directly // so no file_browser/file_info can be used below if ($repo->has_moodle_files()) { $file = repository::get_moodle_file($source); if ($file && $file->is_external_file()) { - $source = $file->get_reference(); + $sourcefield = $file->get_source(); // remember the original source + $record->source = $repo::build_source_field($sourcefield); + $reference = $file->get_reference(); $repo_id = $file->get_repository_id(); $repo = repository::get_repository_by_id($repo_id, $contextid, $repooptions); } } - // {@link repository::build_source_field()} - $sourcefield = $repo->get_file_source_info($source); - $record->source = $repo::build_source_field($sourcefield); - if ($usefilereference) { - $reference = $repo->get_file_reference($source); // get reference life time from repo $record->referencelifetime = $repo->get_reference_file_lifetime($reference); // Check if file exists. @@ -281,13 +284,13 @@ switch ($action) { // If the moodle file is an alias we copy this alias, otherwise we copy the file // {@link repository::copy_to_area()}. - $fileinfo = $repo->copy_to_area($source, $record, $maxbytes); + $fileinfo = $repo->copy_to_area($reference, $record, $maxbytes); echo json_encode($fileinfo); die; } else { // Download file to moodle. - $downloadedfile = $repo->get_file($source, $saveas_filename); + $downloadedfile = $repo->get_file($reference, $saveas_filename); if (empty($downloadedfile['path'])) { $err->error = get_string('cannotdownload', 'repository'); die(json_encode($err));