MDL-49750 mod_data: fix updating file/picture fields breaks references
authorJohannes Burk <me@jojoob.de>
Thu, 25 Jun 2015 14:45:51 +0000 (16:45 +0200)
committerJohannes Burk <me@jojoob.de>
Mon, 5 Oct 2015 09:42:53 +0000 (11:42 +0200)
Use file_save_draft_area_files on file/picture update and
set content to null if file was removed.

mod/data/field/file/field.class.php
mod/data/field/picture/field.class.php

index 22c275d..e29a7d6 100644 (file)
@@ -176,36 +176,22 @@ class data_field_file extends data_field_base {
             $content = $DB->get_record('data_content', array('id'=>$id));
         }
 
-        // delete existing files
-        $fs->delete_area_files($this->context->id, 'mod_data', 'content', $content->id);
+        file_save_draft_area_files($value, $this->context->id, 'mod_data', 'content', $content->id);
 
         $usercontext = context_user::instance($USER->id);
-        $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $value, 'timecreated DESC');
+        $files = $fs->get_area_files($this->context->id, 'mod_data', 'content', $content->id, 'itemid, filepath, filename', false);
 
-        if (count($files)<2) {
-            // no file
+        // We expect no or just one file (maxfiles = 1 option is set for the form_filemanager).
+        if (count($files) == 0) {
+            $content->content = null;
         } else {
-            foreach ($files as $draftfile) {
-                if (!$draftfile->is_directory()) {
-                    $file_record = array(
-                        'contextid' => $this->context->id,
-                        'component' => 'mod_data',
-                        'filearea' => 'content',
-                        'itemid' => $content->id,
-                        'filepath' => '/',
-                        'filename' => $draftfile->get_filename(),
-                    );
-
-                    $content->content = $file_record['filename'];
-
-                    $fs->create_file_from_storedfile($file_record, $draftfile);
-                    $DB->update_record('data_content', $content);
-
-                    // Break from the loop now to avoid overwriting the uploaded file record
-                    break;
-                }
+            $content->content = array_values($files)[0]->get_filename();
+            if (count($files) > 1) {
+                // This should not happen with a consistent database. Inform admins/developers about the inconsistency.
+                debugging('more then one file found in mod_data instance {$this->data->id} file field (field id: {$this->field->id}) area during update data record {$recordid} (content id: {$content->id})', DEBUG_NORMAL);
             }
         }
+        $DB->update_record('data_content', $content);
     }
 
     function text_export_supported() {
index 8db4720..36bcd55 100644 (file)
@@ -235,39 +235,34 @@ class data_field_picture extends data_field_base {
         switch ($names[2]) {
             case 'file':
                 $fs = get_file_storage();
-                $fs->delete_area_files($this->context->id, 'mod_data', 'content', $content->id);
+                file_save_draft_area_files($value, $this->context->id, 'mod_data', 'content', $content->id);
                 $usercontext = context_user::instance($USER->id);
-                $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $value);
-                if (count($files)<2) {
-                    // no file
+                $files = $fs->get_area_files(
+                    $this->context->id,
+                    'mod_data', 'content',
+                    $content->id,
+                    'itemid, filepath, filename',
+                    false);
+
+                // We expect no or just one file (maxfiles = 1 option is set for the form_filemanager).
+                if (count($files) == 0) {
+                    $content->content = null;
                 } else {
-                    $count = 0;
-                    foreach ($files as $draftfile) {
-                        $file_record = array('contextid'=>$this->context->id, 'component'=>'mod_data', 'filearea'=>'content', 'itemid'=>$content->id, 'filepath'=>'/');
-                        if (!$draftfile->is_directory()) {
-                            $file_record['filename'] = $draftfile->get_filename();
-
-                            $content->content = $draftfile->get_filename();
-
-                            $file = $fs->create_file_from_storedfile($file_record, $draftfile);
-
-                            // If the file is not a valid image, redirect back to the upload form.
-                            if ($file->get_imageinfo() === false) {
-                                $url = new moodle_url('/mod/data/edit.php', array('d' => $this->field->dataid));
-                                redirect($url, get_string('invalidfiletype', 'error', $file->get_filename()));
-                            }
-
-                            $DB->update_record('data_content', $content);
-                            $this->update_thumbnail($content, $file);
-
-                            if ($count > 0) {
-                                break;
-                            } else {
-                                $count++;
-                            }
-                        }
+                    $file = array_values($files)[0];
+
+                    if (count($files) > 1) {
+                        // This should not happen with a consistent database. Inform admins/developers about the inconsistency.
+                        debugging('more then one file found in mod_data instance {$this->data->id} picture field (field id: {$this->field->id}) area during update data record {$recordid} (content id: {$content->id})', DEBUG_NORMAL);
+                    }
+
+                    if ($file->get_imageinfo() === false) {
+                        $url = new moodle_url('/mod/data/edit.php', array('d' => $this->field->dataid));
+                        redirect($url, get_string('invalidfiletype', 'error', $file->get_filename()));
                     }
+                    $content->content = $file->get_filename();
+                    $this->update_thumbnail($content, $file);
                 }
+                $DB->update_record('data_content', $content);
 
                 break;