From 48e62f035eab6c8f7d54d30a3a8ea2fc51cd4d36 Mon Sep 17 00:00:00 2001
From: gloas <gloas@afi-sa.fr>
Date: Wed, 4 Apr 2018 14:20:54 +0200
Subject: [PATCH] dev #68179 fix thumbnail for storyPlayR + upgrade dashboard

---
 library/Class/Album.php                       | 12 ++-
 library/Class/Upload.php                      | 23 +++--
 .../WebService/BibNumerique/Vignette.php      | 99 +++++++++++++++----
 .../View/Helper/DigitalResource/Dashboard.php | 25 ++++-
 .../StoryPlayR/tests/StoryPlayRTest.php       | 19 ++++
 5 files changed, 144 insertions(+), 34 deletions(-)

diff --git a/library/Class/Album.php b/library/Class/Album.php
index aa0c76fc2ad..f5b71a52083 100644
--- a/library/Class/Album.php
+++ b/library/Class/Album.php
@@ -683,15 +683,17 @@ class Class_Album extends Storm_Model_Abstract {
    */
   public function receiveFile() {
     $to_delete = [$this->getVignettePath(), $this->getThumbnailPath()];
-    $on_update = function($old_file, $new_file) use ($to_delete) {
-      if ($old_file && $old_file != $new_file)
+
+    $on_update = function($old_file, $new_file) use ($to_delete)
+      {
+        if ($old_file && $old_file != $new_file)
         foreach($to_delete as $item)
           $this->getFileSystem()->unlink($item);
 
-      $this->createThumbnail();
+        $this->createThumbnail();
 
-      return true;
-    };
+        return true;
+      };
 
     $handler = $this->getUploadHandler('fichier')
                     ->setAllowedExtensions(['jpg', 'gif', 'png', 'jpeg', 'bro']);
diff --git a/library/Class/Upload.php b/library/Class/Upload.php
index 1ad7a6ece4a..0bcc25ecb8e 100644
--- a/library/Class/Upload.php
+++ b/library/Class/Upload.php
@@ -296,6 +296,7 @@ class Class_Upload {
       $this->setError($this->_('Transfert impossible, champ de fichier introuvable'));
       return false;
     }
+
     if ($this->hasErrorCodeOnFile()) {
       $this->setError($this->getPhpFileUploadErrors()[$_FILES[$this->_name]['error']]);
       return false;
@@ -323,18 +324,24 @@ class Class_Upload {
       return false;
     }
 
-    $parts = explode('.', $_FILES[$this->_name]['name']);
-    $ext = end($parts);
 
-    $allowedExtensions = $this->getAllowedExtensions();
-    if ((0 < count($allowedExtensions))
-        && (!in_array($ext, $allowedExtensions))) {
-      $this->setError(sprintf($this->_('Le fichier n\'est pas de type %s'), implode(', ', $allowedExtensions)));
+    if(!$this->_isExtensionValid()) {
+      $this->setError(sprintf($this->_('Le fichier n\'est pas de type %s'), implode(', ', $this->getAllowedExtensions())));
       return false;
     }
 
     return true;
   }
-}
 
-?>
\ No newline at end of file
+
+  protected function _isExtensionValid() {
+    $allowedExtensions = $this->getAllowedExtensions();
+    if(0 == count($allowedExtensions))
+      return true;
+
+    $parts = explode('.', $_FILES[$this->_name]['name']);
+    $ext = end($parts);
+
+    return in_array($ext, $allowedExtensions);
+  }
+}
diff --git a/library/Class/WebService/BibNumerique/Vignette.php b/library/Class/WebService/BibNumerique/Vignette.php
index a233c79ad65..f663be676c9 100644
--- a/library/Class/WebService/BibNumerique/Vignette.php
+++ b/library/Class/WebService/BibNumerique/Vignette.php
@@ -20,10 +20,14 @@
  */
 
 class Class_WebService_BibNumerique_Vignette extends Class_WebService_Abstract {
+  use Trait_Translator;
+
   protected static $_instance;
-  protected $_file_writer;
-  protected $_updload_mover;
-  protected $_url_validator;
+
+  protected
+    $_file_writer,
+    $_updload_mover,
+    $_url_validator;
 
 
   public static function getInstance() {
@@ -50,29 +54,86 @@ class Class_WebService_BibNumerique_Vignette extends Class_WebService_Abstract {
 
 
   public function updateAlbum($album) {
-    $url_poster = $album->getPoster();
-    if (!($url_poster && $this->_url_validator->isValid($url_poster)))
-      return $this;
+    if ($this->downloadPoster($album))
+      $album->save();
+
+    return $this;
+  }
+
 
-    if (!$image = $this->httpGet($url_poster))
-      return $this;
+  public function isUrlValid($url) {
+    if(!$url)
+      return false;
+
+    return $this->_url_validator->isValid($url);
+  }
 
-    $parts = explode('/', $url_poster);
+
+  public function downloadPoster($album) {
+    if(!$album)
+      return;
+
+    $url = $album->getPoster();
+
+    if (!$this->isUrlValid($url)) {
+      $this->getLogger()->log($this->_('URL "%s" invalide', $url));
+      return;
+    }
+
+    if (!$poster = $this->httpGet($url)) {
+      $this->getLogger()->log($this->_('Impossible de télécharger l\'image "%s" sur le serveur', $url));
+      return;
+    }
+
+    if(!$filename = $this->_initFilename($url, $poster, $album))
+      return;
+
+    $album->setUploadMover('fichier', $this->_upload_mover);
+
+    if(!$album->receiveFile()) {
+      $this->getLogger()->log($this->_('Impossible d\'ajouter l\'image "%s" à l\'album "%s"',
+                                       $filename,
+                                       $album->getTitre()));
+      $this->getLogger()->log(implode(BR, $album->getErrors()));
+      return;
+    }
+
+    return $this;
+  }
+
+
+  protected function _initFilename($url, $poster, $album) {
+    $parts = explode('/', $url);
     $filename = array_pop($parts);
-    $temp_name = PATH_TEMP.$filename;
-    if (false === $this->getFileWriter()->putContents($temp_name, $image))
-      return $this;
+    $filename = $this->_formatFilename($filename, $album);
+    $temp_name = PATH_TEMP . $filename;
+
+    if (false === $this->getFileWriter()->putContents($temp_name, $poster)) {
+      $this->getLogger()->log($this->_('Impossible d\'enregister l\'image "%s" dans "%s"',
+                                         $url,
+                                         $temp_name));
+      return;
+    }
 
     $_FILES['fichier'] = ['name' => $filename,
                           'tmp_name' => $temp_name,
-                          'size' => strlen($image)];
+                          'size' => strlen($poster)];
 
-    $album->setUploadMover('fichier', $this->_upload_mover);
+    return $filename;
+  }
 
-    $album->receiveFile();
-    $album->save();
 
-    return $this;
+  protected function _formatFilename($filename, $album) {
+    $parts = explode('.', $filename);
+    return (1 == count($parts))
+      ? $filename . '_' . Storm_Inflector::camelize($album->getTitre()) . '.jpeg'
+      : $filename;
+  }
+
+
+  public function getDownloadPosterLog($album) {
+    $this->downloadPoster($album);
+    return $this->getLogger()->getMessages();
   }
 
 
@@ -86,6 +147,4 @@ class Class_WebService_BibNumerique_Vignette extends Class_WebService_Abstract {
       $this->_file_writer = new Class_FileWriter();
     return $this->_file_writer;
   }
-}
-
-?>
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/DigitalResource/Dashboard.php b/library/ZendAfi/View/Helper/DigitalResource/Dashboard.php
index 2c6f80891df..7e35f508aff 100644
--- a/library/ZendAfi/View/Helper/DigitalResource/Dashboard.php
+++ b/library/ZendAfi/View/Helper/DigitalResource/Dashboard.php
@@ -343,11 +343,13 @@ class ZendAfi_View_Helper_DigitalResource_Dashboard extends ZendAfi_View_Helper_
       : $this->_tag('p', $this->_('Cette ressource ne prend pas en charge l\'affichage du l\'url de moissonnage'), ['class' => 'error']);
 
     $count = Class_Album::countBy(['type_doc_id' => $this->_config->getDocType()]);
+    $first_album = Class_Album::findFirstBy(['type_doc_id' => $this->_config->getDocType(),
+                                             'order' => 'titre asc']);
     $albums_link = $count
       ? $this->view->tagAnchor($this->view->absoluteUrl(['module' => 'admin',
                                                          'controller' => 'album',
                                                          'action' => 'index',
-                                                         'cat_id' => Class_Album::findFirstBy(['type_doc_id' => $this->_config->getDocType()])->getRootCategoryId()], null, true),
+                                                         'cat_id' => $first_album->getRootCategoryId()], null, true),
                                $this->_('Voir les albums'),
                                ['target' => '_blank'])
       : '';
@@ -358,6 +360,15 @@ class ZendAfi_View_Helper_DigitalResource_Dashboard extends ZendAfi_View_Helper_
       . $albums_link
       : $this->_tag('p', $this->_('Aucun album présent pour cette ressource'), ['class' => 'error']);
 
+    $html [] = $count
+      ? ($this->_tag('h4',
+                     $this->_('Tentative de vignettage de l\'album "%s" : ', $first_album->getTitre()))
+         . $this->view->tagAnchor($first_album->getPoster(),
+                             $this->_('Image source : %s', $first_album->getPoster()),
+                             ['target' => '_blank'])
+         . $this->_renderThumbnailerLog($first_album))
+      : $this->_tag('p', $this->_('Le vignettage n\'est pas testable sans album'), ['class' => 'error']);
+
     $count = Class_Notice::countBy(['type_doc' => $this->_config->getDocType()]);
 
     $records_link = $count ?
@@ -378,4 +389,16 @@ class ZendAfi_View_Helper_DigitalResource_Dashboard extends ZendAfi_View_Helper_
 
     return implode($html);
   }
+
+
+  protected function _renderThumbnailerLog($album) {
+    $thumbnailer = Class_WebService_BibNumerique_Vignette::getInstance();
+    $thumbnailer->setLogger(new Class_Log);
+
+    if(!$errors = $thumbnailer->getDownloadPosterLog($album))
+      return $this->_tag('p', $this->_('Vignette de l\'album : '
+                                       . $this->view->tagImg(Class_Url::absolute($album->getThumbnailUrl()))));
+
+    return $this->_tag('p', implode(BR, $errors), ['class' => 'error']);
+  }
 }
\ No newline at end of file
diff --git a/library/digital_resources/StoryPlayR/tests/StoryPlayRTest.php b/library/digital_resources/StoryPlayR/tests/StoryPlayRTest.php
index 0f4766a9124..02b214f0538 100644
--- a/library/digital_resources/StoryPlayR/tests/StoryPlayRTest.php
+++ b/library/digital_resources/StoryPlayR/tests/StoryPlayRTest.php
@@ -106,6 +106,13 @@ class StoryPlayRDashboardActivatedTest extends StoryPlayRActivatedTestCase {
     Class_AdminVar::set('StoryPlayR_OPDS_CATALOG_URL',
                         'https://preprod.storyplayr.com/api/opds-with-links');
 
+    $album = $this->fixture('Class_Album',
+               ['id' => 20,
+                'titre' => '10 moutons',
+                'type_doc_id' => 'StoryPlayR'
+               ]);
+    $album->addPosterURI('https://preprod.storyplayr.com/api/library/17fcdd4f-0c1c-4515-a0cf-594f41b03550/thumbnail/large');
+    $album->save();
     ZendAfi_Auth::getInstance()->logUser($this->fixture('Class_Users',
                                                         ['id' => 2,
                                                          'login' => 'admin',
@@ -137,6 +144,18 @@ class StoryPlayRDashboardActivatedTest extends StoryPlayRActivatedTestCase {
   public function harvestUrlShouldContainsOpdsCatalogUrlAndProviderAndMediathequeid() {
     $this->assertXPath('//a[@href="https://preprod.storyplayr.com/api/opds-with-links?portalProvider=bokeh&mediathequeid=123456"]');
   }
+
+
+  /** @test */
+  public function sourceImageShouldBeValid() {
+    $this->assertXPathContentContains('//a','Image source : https://preprod');
+  }
+
+
+  /** @test */
+  public function vignetteShouldBePresent() {
+    $this->assertXPath("//img[contains(@src,'userfiles/album/20/thumb_20_large_10Moutons.jpeg')]");
+  }
 }
 
 
-- 
GitLab