From 33234967511be83a8ec7bceb64b62eeb9ffbb04f Mon Sep 17 00:00:00 2001
From: gloas <gloas@afi-sa.fr>
Date: Thu, 28 Sep 2017 14:30:22 +0200
Subject: [PATCH] dev #59187 add redmine attachment button

---
 FEATURES/59187                                | 10 ++++
 VERSIONS_WIP/59187                            |  1 +
 .../admin/controllers/RedmineController.php   | 20 ++++++-
 .../views/scripts/redmine/edit-issue.phtml    |  1 +
 library/Class/WebService/Redmine.php          | 22 ++++++-
 library/ZendAfi/Form/Redmine/Issue.php        | 58 +++++++++++++++----
 public/opac/js/file_uploader.js               | 43 ++++++++++++++
 .../controllers/RedmineControllerTest.php     | 22 ++++++-
 8 files changed, 163 insertions(+), 14 deletions(-)
 create mode 100644 FEATURES/59187
 create mode 100644 VERSIONS_WIP/59187
 create mode 100644 public/opac/js/file_uploader.js

diff --git a/FEATURES/59187 b/FEATURES/59187
new file mode 100644
index 00000000000..c53c5b2f5fe
--- /dev/null
+++ b/FEATURES/59187
@@ -0,0 +1,10 @@
+        '59187' =>
+            ['Label' => $this->_('[Explo] Redmine : pouvoir uploader des fichiers dans les tickets back office'),
+             'Desc' => '',
+             'Image' => '',
+             'Video' => '',
+             'Category' => '',
+             'Right' => function($feature_description, $user) {return true;},
+             'Wiki' => '',
+             'Test' => '',
+             'Date' => '2017-09-28'],
\ No newline at end of file
diff --git a/VERSIONS_WIP/59187 b/VERSIONS_WIP/59187
new file mode 100644
index 00000000000..0a50e0f9959
--- /dev/null
+++ b/VERSIONS_WIP/59187
@@ -0,0 +1 @@
+ - ticket #59187 : [Explo] Redmine : pouvoir uploader des fichiers dans les tickets back office
\ No newline at end of file
diff --git a/application/modules/admin/controllers/RedmineController.php b/application/modules/admin/controllers/RedmineController.php
index d6a04c54a70..e873b392219 100644
--- a/application/modules/admin/controllers/RedmineController.php
+++ b/application/modules/admin/controllers/RedmineController.php
@@ -111,7 +111,7 @@ class Admin_RedmineController extends ZendAfi_Controller_Action {
         && $form->isValid($this->_request->getPost())) {
       $issue->updateAttributes($form->getValues());
 
-      if ($service->createIssue($issue)) {
+      if ($response = $service->createIssue($issue)) {
         $this->_helper->notify($this->_('Demande enregistrée'));
         $this->_redirectToIndex();
         return;
@@ -153,6 +153,7 @@ class Admin_RedmineController extends ZendAfi_Controller_Action {
         && $form->isValid($this->_request->getPost())) {
       $issue->updateAttributes($form->getValues());
       $service->updateIssue($issue);
+      $service->attachToIssue($issue);
 
       $this->_helper->notify($this->_('Demande #%s enregistrée', $issue->getid()));
       $this->_redirectToIndex();
@@ -160,6 +161,23 @@ class Admin_RedmineController extends ZendAfi_Controller_Action {
   }
 
 
+  public function uploadFileAction() {
+    if (!$this->_request->isPost())
+      return $this->_helper->json($this->_request->getPost());
+
+    $library = Class_Bib::find($this->_getParam('id_lib', 0));
+    $service = new Class_WebService_Redmine($library);
+
+    if (null !== $message = $service->validate())
+      return $this->_helper->json($this->_request->getPost());
+
+    if (!$response = $service->uploadFile($this->_getParam('data')))
+      return $this->_helper->json($this->_request->getPost());
+
+    return $this->_helper->json(json_decode($response));
+  }
+
+
   protected function withResponseDo($data, $call_back) {
     $error_message = $this->view->getHelper('Redmine_AccountStatus')->connectionFail();
 
diff --git a/application/modules/admin/views/scripts/redmine/edit-issue.phtml b/application/modules/admin/views/scripts/redmine/edit-issue.phtml
index 970664867c8..21d88991d74 100644
--- a/application/modules/admin/views/scripts/redmine/edit-issue.phtml
+++ b/application/modules/admin/views/scripts/redmine/edit-issue.phtml
@@ -1,5 +1,6 @@
 <div class="form">
   <fieldset>
+   <legend><?php echo $this->_('Titre');?></legend>
     <table>
       <tr>
         <td></td>
diff --git a/library/Class/WebService/Redmine.php b/library/Class/WebService/Redmine.php
index daa11a004ac..6feddd5640b 100644
--- a/library/Class/WebService/Redmine.php
+++ b/library/Class/WebService/Redmine.php
@@ -84,6 +84,11 @@ class Class_WebService_Redmine extends Class_WebService_Abstract {
   }
 
 
+  protected function _getAttachmentApi() {
+    return $this->getClient()->api('attachment');
+  }
+
+
   protected function getIssueStatusApi() {
     return $this->getClient()->api('issue_status');
   }
@@ -198,7 +203,16 @@ class Class_WebService_Redmine extends Class_WebService_Abstract {
 
   public function updateIssue($issue) {
     return $this->getIssueApi()
-                ->update($issue->getid(), $issue->getUpdateParams());
+         ->update($issue->getid(), $issue->getUpdateParams());
+  }
+
+
+  public function attachToIssue($issue) {
+    return $this->getIssueApi()
+         ->attach($issue->getid(),
+                  ['token' => $issue->gettoken(),
+                   'filename' => $issue->getfilename(),
+                   'content_type' => $issue->getfiletype()]);
   }
 
 
@@ -360,6 +374,12 @@ class Class_WebService_Redmine extends Class_WebService_Abstract {
   }
 
 
+  public function uploadFile($json) {
+    return $this->_getAttachmentApi()
+                ->upload($json);
+  }
+
+
   protected function getCustomOptions($id) {
     $options = [];
     foreach ($this->getCustomFields() as $field) {
diff --git a/library/ZendAfi/Form/Redmine/Issue.php b/library/ZendAfi/Form/Redmine/Issue.php
index 4c902d8afdc..34a2a1d87e8 100644
--- a/library/ZendAfi/Form/Redmine/Issue.php
+++ b/library/ZendAfi/Form/Redmine/Issue.php
@@ -23,8 +23,13 @@
 class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form {
   protected
     $_issue,
-    $_status = [], $_priorities = [], $_modules = [],
-    $_default_priority, $_default_module, $_default_contact, $_default_customer;
+    $_status = [],
+    $_priorities = [],
+    $_modules = [],
+    $_default_priority,
+    $_default_module,
+    $_default_contact,
+    $_default_customer;
 
 
   public static function newWithIssue($issue, $service) {
@@ -65,6 +70,30 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form {
 
 
   protected function initInputs() {
+
+    Class_ScriptLoader::getInstance()
+      ->addOPACScript('file_uploader.js')
+      ->addJqueryReady(sprintf('$("#attachment").file_uploader("%s");',
+                               Class_Url::relative(['module' => 'admin',
+                                                    'controller' => 'redmine',
+                                                    'action' => 'upload-file',
+                                                    'id_lib' => Class_Url::getParam('id_lib')])));
+
+    $this
+      ->addElement('file',
+                   'attachment',
+                   ['label' => $this->_('Pièce jointe'),
+                    'destination' => PATH_TEMP])
+
+      ->addElement('hidden',
+                   'token')
+
+      ->addElement('hidden',
+                   'filename')
+
+      ->addElement('hidden',
+                   'filetype');
+
     if (!$this->_issue->getid()) {
       $this
         ->addElement('text',
@@ -94,7 +123,10 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form {
                       'value' => '',
                       'placeholder' => $this->_('Merci de préciser les différentes étapes pour reproduire le problème rencontré, l\'adresse de la page, si il faut être connecté avec un compte particulier')])
 
-        ->addDisplayGroup(['subject', 'description', 'technical_informations'],
+        ->addDisplayGroup(['subject',
+                           'description',
+                           'technical_informations',
+                           'attachment'],
                           'common',
                           ['legend' => ''])
         ;
@@ -103,8 +135,11 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form {
 
     if ($this->_issue->getid()) {
       $this
-        ->addElement('textarea', 'notes', ['rows' => 5, 'cols' => 75])
-        ->addDisplayGroup(['notes'], 'default', ['legend' => $this->_('Nouvelle note')]);
+        ->addElement('textarea', 'notes', [
+                                           'label' => $this->_('Note'),
+                                           'rows' => 5, 'cols' => 75])
+        ->addDisplayGroup(['notes',
+                           'attachment'], 'default', ['legend' => $this->_('Nouvelle note')]);
     }
 
 
@@ -136,8 +171,11 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form {
                        'rows' => 2, 'cols' => 50,
                        'value' => $this->_issue->getContact() ? $this->_issue->getContact() : $this->getDefaultContact()])
 
-
-         ->addDisplayGroup(['customer', 'status_id', 'priority', 'module', 'contact'],
+         ->addDisplayGroup(['customer',
+                            'status_id',
+                            'priority',
+                            'module',
+                            'contact'],
                            'properties',
                            ['legend' => $this->_('Propriétés')]);
 
@@ -177,9 +215,9 @@ class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form {
       return;
 
     if ($library->hasMail() || $library->hasTelephone())
-        return implode(' / ', array_filter([$library->getLibelle(),
-                                            $library->getMail(),
-                                            $library->getTelephone()]));
+      return implode(' / ', array_filter([$library->getLibelle(),
+                                          $library->getMail(),
+                                          $library->getTelephone()]));
   }
 
 
diff --git a/public/opac/js/file_uploader.js b/public/opac/js/file_uploader.js
new file mode 100644
index 00000000000..dfdec11a4d8
--- /dev/null
+++ b/public/opac/js/file_uploader.js
@@ -0,0 +1,43 @@
+(function ( $ ) {
+  $.fn.file_uploader = function(url) {
+    var input_file = $(this);
+    $(input_file).change(function(event) {
+      postAjax(event);
+    });
+
+    var postAjax = function(event) {
+      var image_preview = input_file.closest('tr').find('img');
+      if(0 == image_preview.length) {
+        input_file.closest('td').append('<img style="display: block; width: 500px; margin: 1ex 0;"></img>')
+        image_preview = input_file.closest('tr').find('img');
+      }
+
+      var file = null,
+          is_image = null;
+
+      if((!(file = event.target.files[0])) ||
+         (!(is_image = file.type.match(/image.*/)))) {
+        image_preview.hide();
+        return false;
+      }
+
+      var reader = new FileReader();
+
+      reader.onloadend = function(e) {
+        var data_url = reader.result;
+        var image = new Image();
+        image.src = data_url;
+        image_preview.attr('src', data_url);
+        image_preview.show();
+        $.post(url,
+               {data: data_url},
+               function(data) {
+                 input_file.closest('form').find('#token').attr('value', data.upload.token);
+                 input_file.closest('form').find('#filename').attr('value', file.name);
+                 input_file.closest('form').find('#filetype').attr('value', file.type);
+               });
+      };
+      reader.readAsDataURL(file);
+    };
+  }
+} (jQuery));
diff --git a/tests/application/modules/admin/controllers/RedmineControllerTest.php b/tests/application/modules/admin/controllers/RedmineControllerTest.php
index 2be95ef46d1..6aa004397e2 100644
--- a/tests/application/modules/admin/controllers/RedmineControllerTest.php
+++ b/tests/application/modules/admin/controllers/RedmineControllerTest.php
@@ -726,13 +726,14 @@ class Admin_RedmineControllerAddIssueTest extends Admin_RedmineControllerFixture
 
 
   public function data_form() {
-    return [ ['//form'],
+    return [['//form'],
             ['//input[@id="subject"]'],
             ['//select[@id="priority"]//option[@value="Normale"][@selected]'],
             ['//select[@id="module"]'],
             ['//textarea[@id="description"]'],
             ['//textarea[@id="technical_informations"][@readonly][contains(text(), "Url :")]'],
-            ['//textarea[@id="contact"]']];
+            ['//textarea[@id="contact"]'],
+            ['//input[@type="file"]']];
   }
 
 
@@ -743,4 +744,21 @@ class Admin_RedmineControllerAddIssueTest extends Admin_RedmineControllerFixture
   public function formShouldContains($tag) {
     $this->assertXPath($tag, $this->_response->getBody());
   }
+}
+
+
+
+
+
+class Admin_RedmineControllerUploadFileTest extends Admin_RedmineControllerFixtureAbstractTest{
+  public function setUp() {
+    parent::setUp();
+    $this->postDispatch('admin/redmine/upload-file/id_lib/1', []);
+  }
+
+
+  /** @test */
+  public function shouldReturnJsonResponse() {
+    $this->assertEquals('  ', $this->_response->getBody());
+  }
 }
\ No newline at end of file
-- 
GitLab