MDL-34290 repository API: do not confuse source and reference
authorMarina Glancy <marina@moodle.com>
Tue, 31 Jul 2012 02:17:07 +0000 (10:17 +0800)
committerMarina Glancy <marina@moodle.com>
Wed, 29 Aug 2012 03:56:14 +0000 (11:56 +0800)
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
repository/filepicker.php
repository/lib.php
repository/repository_ajax.php

index 186e63b..9d73e35 100644 (file)
@@ -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']);
             }
         }
     }
index fd16e66..1b67331 100644 (file)
@@ -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) {
index de8448b..8510f95 100644 (file)
@@ -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;
     }
 
     /**
index d9f3cea..baf59ef 100644 (file)
@@ -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));