From 9b65a0809584ddec471595f6379bec1faac35fec Mon Sep 17 00:00:00 2001
From: Andrew Nicols <andrew@nicols.co.uk>
Date: Tue, 25 Nov 2014 07:58:48 +0800
Subject: [PATCH] MDL-47475 mod_assign: Copy files to other group members for
 editpdf

---
 .../editpdf/classes/document_services.php     | 18 ++---
 .../feedback/editpdf/classes/page_editor.php  | 49 ++++++++----
 .../tests/behat/group_annotations.feature     | 74 +++++++++++++++++++
 3 files changed, 118 insertions(+), 23 deletions(-)
 create mode 100644 mod/assign/feedback/editpdf/tests/behat/group_annotations.feature

diff --git a/mod/assign/feedback/editpdf/classes/document_services.php b/mod/assign/feedback/editpdf/classes/document_services.php
index 912bd8addff..5c60de990e7 100644
--- a/mod/assign/feedback/editpdf/classes/document_services.php
+++ b/mod/assign/feedback/editpdf/classes/document_services.php
@@ -44,6 +44,8 @@ class document_services {
     const PAGE_IMAGE_FILEAREA = 'pages';
     /** File area for readonly page images */
     const PAGE_IMAGE_READONLY_FILEAREA = 'readonlypages';
+    /** File area for the stamps */
+    const STAMPS_FILEAREA = 'stamps';
     /** Filename for combined pdf */
     const COMBINED_PDF_FILENAME = 'combined.pdf';
 
@@ -363,6 +365,9 @@ class document_services {
         $record->filepath = '/';
         $fs = \get_file_storage();
 
+        // Remove the existing content of the filearea.
+        $fs->delete_area_files($record->contextid, $record->component, $record->filearea, $record->itemid);
+
         $files = array();
         for ($i = 0; $i < $pagecount; $i++) {
             $image = $pdf->get_image($i);
@@ -421,14 +426,13 @@ class document_services {
         $fs = \get_file_storage();
 
         // If we are after the readonly pages...
-        $copytoreadonly = false;
         if ($readonly) {
             $filearea = self::PAGE_IMAGE_READONLY_FILEAREA;
             if ($fs->is_area_empty($contextid, $component, $filearea, $itemid)) {
-                // We have a problem here, we were supposed to find the files...
-                // let's fallback on the other area, and copy the files to the readonly area.
-                $copytoreadonly = true;
-                $filearea = self::PAGE_IMAGE_FILEAREA;
+                // We have a problem here, we were supposed to find the files.
+                // Attempt to re-generate the pages from the combined images.
+                self::generate_page_images_for_attempt($assignment, $userid, $attemptnumber);
+                self::copy_pages_to_readonly_area($assignment, $grade);
             }
         }
 
@@ -460,10 +464,6 @@ class document_services {
                     $pages[$pagenumber] = $file;
                 }
                 ksort($pages);
-
-                if ($copytoreadonly) {
-                    self::copy_pages_to_readonly_area($assignment, $grade);
-                }
             }
         }
 
diff --git a/mod/assign/feedback/editpdf/classes/page_editor.php b/mod/assign/feedback/editpdf/classes/page_editor.php
index afa01ef866e..ace040325a0 100644
--- a/mod/assign/feedback/editpdf/classes/page_editor.php
+++ b/mod/assign/feedback/editpdf/classes/page_editor.php
@@ -310,8 +310,9 @@ class page_editor {
     }
 
     /**
-     * This function copies annotations and comments from the source user
-     * to the current group member being processed when using applytoall.
+     * Copy annotations, comments, pages, and other required content from the source user to the current group member
+     * being procssed when using applytoall.
+     *
      * @param int|\assign $assignment
      * @param stdClass $grade
      * @param int $sourceuserid
@@ -327,6 +328,8 @@ class page_editor {
         $sourceusergrade = $assignment->get_user_grade($sourceuserid, true, $grade->attemptnumber);
         $annotations = $DB->get_records('assignfeedback_editpdf_annot', array('gradeid' => $sourceusergrade->id, 'draft' => 1));
         $comments = $DB->get_records('assignfeedback_editpdf_cmnt', array('gradeid' => $sourceusergrade->id, 'draft' => 1));
+        $contextid = $assignment->get_context()->id;
+        $sourceitemid = $sourceusergrade->id;
 
         // Add annotations and comments to current user to generate feedback file.
         foreach ($annotations as $annotation) {
@@ -338,24 +341,42 @@ class page_editor {
             $DB->insert_record('assignfeedback_editpdf_cmnt', $comment);
         }
 
-        // Delete the existing stamps and copy the source ones.
         $fs = get_file_storage();
-        $fs->delete_area_files($assignment->get_context()->id, 'assignfeedback_editpdf', 'stamps', $grade->id);
-        if ($files = $fs->get_area_files($assignment->get_context()->id,
-                                         'assignfeedback_editpdf',
-                                         'stamps',
-                                         $sourceusergrade->id,
-                                         "filename",
-                                         false)) {
+
+        // Copy the stamp files.
+        self::replace_files_from_to($fs, $contextid, $sourceitemid, $grade->id, document_services::STAMPS_FILEAREA, true);
+
+        // Copy the PAGE_IMAGE_FILEAREA files.
+        self::replace_files_from_to($fs, $contextid, $sourceitemid, $grade->id, document_services::PAGE_IMAGE_FILEAREA);
+
+        return true;
+    }
+
+    /**
+     * Replace the area files in the specified area with those in the source item id.
+     *
+     * @param \file_storage $fs The file storage class
+     * @param int $contextid The ID of the context for the assignment.
+     * @param int $sourceitemid The itemid to copy from - typically the source grade id.
+     * @param int $itemid The itemid to copy to - typically the target grade id.
+     * @param string $area The file storage area.
+     * @param bool $includesubdirs Whether to copy the content of sub-directories too.
+     */
+    public static function replace_files_from_to($fs, $contextid, $sourceitemid, $itemid, $area, $includesubdirs = false) {
+        $component = 'assignfeedback_editpdf';
+        // Remove the existing files within this area.
+        $fs->delete_area_files($contextid, $component, $area, $itemid);
+
+        // Copy the files from the source area.
+        if ($files = $fs->get_area_files($contextid, $component, $area, $sourceitemid,
+                                         "filename", $includesubdirs)) {
             foreach ($files as $file) {
                 $newrecord = new \stdClass();
-                $newrecord->contextid = $assignment->get_context()->id;
-                $newrecord->itemid = $grade->id;
+                $newrecord->contextid = $contextid;
+                $newrecord->itemid = $itemid;
                 $fs->create_file_from_storedfile($newrecord, $file);
             }
         }
-
-        return true;
     }
 
     /**
diff --git a/mod/assign/feedback/editpdf/tests/behat/group_annotations.feature b/mod/assign/feedback/editpdf/tests/behat/group_annotations.feature
new file mode 100644
index 00000000000..1bdb027afb1
--- /dev/null
+++ b/mod/assign/feedback/editpdf/tests/behat/group_annotations.feature
@@ -0,0 +1,74 @@
+@mod @mod_assign @assignfeedback @assignfeedback_editpdf @_file_upload
+Feature: In a group assignment, teacher can annotate PDF files for all users
+  In order to provide visual report on a graded PDF for all users
+  As a teacher
+  I need to use the PDF editor for a group assignment
+
+  @javascript
+  Scenario: Submit a PDF file as a student and annotate the PDF as a teacher
+    Given ghostscript is installed
+    And the following "courses" exist:
+      | fullname | shortname | category | groupmode |
+      | Course 1 | C1 | 0 | 1 |
+    And the following "users" exist:
+      | username | firstname | lastname | email |
+      | teacher1 | Teacher | 1 | teacher1@example.com |
+      | student1 | Student | 1 | student1@example.com |
+      | student2 | Student | 2 | student2@example.com |
+    And the following "course enrolments" exist:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+      | student1 | C1 | student |
+      | student2 | C1 | student |
+    And the following "groups" exist:
+      | name     | course | idnumber |
+      | G1       | C1     | G1       |
+    And the following "group members" exist:
+      | user     | group |
+      | student1 | G1    |
+      | student2 | G1    |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I add a "Assignment" to section "1" and I fill the form with:
+      | Assignment name                   | Test assignment name |
+      | Description                       | Submit your PDF file |
+      | assignsubmission_file_enabled     | 1 |
+      | Maximum number of uploaded files  | 1 |
+      | Students submit in groups         | Yes |
+    And I log out
+    And I log in as "student1"
+    And I follow "Course 1"
+    And I follow "Test assignment name"
+    And I press "Add submission"
+    And I upload "mod/assign/feedback/editpdf/tests/fixtures/submission.pdf" file to "File submissions" filemanager
+    And I press "Save changes"
+    And I should see "Submitted for grading"
+    And I should see "submission.pdf"
+    And I should see "Not graded"
+    And I log out
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I follow "Test assignment name"
+    And I follow "View/grade all submissions"
+    And I click on "Grade" "link" in the "Submitted for grading" "table_row"
+    And I follow "Launch PDF editor..."
+    And I click on ".navigate-next-button" "css_element"
+    And I click on ".stampbutton" "css_element"
+    And I click on ".drawingcanvas" "css_element"
+    And I click on "Close" "button"
+    And I press "Save changes"
+    And I should see "The grade changes were saved"
+    And I log out
+    And I log in as "student1"
+    And I follow "Course 1"
+    And I follow "Test assignment name"
+    When I follow "View annotated PDF..."
+    Then I should see "Annotate PDF"
+    And I click on "Close" "button"
+    And I log out
+    And I log in as "student2"
+    And I follow "Course 1"
+    And I follow "Test assignment name"
+    And I follow "View annotated PDF..."
+    And I should see "Annotate PDF"