From e28b080c5a9da5b2b94e690a55a6bf63637b0e1d Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Wed, 8 Jul 2015 13:43:18 +0200 Subject: [PATCH] Extract thumbnail manager classes from appbox --- .../Thumbnail/AbstractThumbnailManager.php | 126 +++++++++++++++ .../Thumbnail/CollectionThumbnailManager.php | 69 +++++++++ .../Thumbnail/DataboxThumbnailManager.php | 48 ++++++ .../Core/Thumbnail/ThumbnailManager.php | 21 +++ .../Core/Thumbnail/ThumbnailedElement.php | 13 ++ lib/classes/appbox.php | 145 ++---------------- lib/classes/collection.php | 30 +++- lib/classes/databox.php | 42 +++-- 8 files changed, 348 insertions(+), 146 deletions(-) create mode 100644 lib/Alchemy/Phrasea/Core/Thumbnail/AbstractThumbnailManager.php create mode 100644 lib/Alchemy/Phrasea/Core/Thumbnail/CollectionThumbnailManager.php create mode 100644 lib/Alchemy/Phrasea/Core/Thumbnail/DataboxThumbnailManager.php create mode 100644 lib/Alchemy/Phrasea/Core/Thumbnail/ThumbnailManager.php create mode 100644 lib/Alchemy/Phrasea/Core/Thumbnail/ThumbnailedElement.php diff --git a/lib/Alchemy/Phrasea/Core/Thumbnail/AbstractThumbnailManager.php b/lib/Alchemy/Phrasea/Core/Thumbnail/AbstractThumbnailManager.php new file mode 100644 index 0000000000..eb570c383e --- /dev/null +++ b/lib/Alchemy/Phrasea/Core/Thumbnail/AbstractThumbnailManager.php @@ -0,0 +1,126 @@ +alchemyst = $alchemyst; + $this->application = $application; + $this->filesystem = $filesystem; + $this->rootPath = $rootPath; + } + + protected function validateFileMimeType(File $file) + { + if (!in_array(mb_strtolower($file->getMimeType()), self::$allowedMimeTypes)) { + throw new \InvalidArgumentException('Invalid file format'); + } + } + + /** + * @param MediaInterface $media + * @param int $maxWidth + * @param int $maxHeight + * @return bool + */ + protected function shouldResize($media, $maxWidth, $maxHeight) + { + if (! $media instanceof Image && ! $media instanceof Video) { + return false; + } + + return $media->getWidth() > $maxWidth || $media->getHeight() > $maxHeight; + } + + /** + * @param ImageSpecification $imageSpec + * @param int $width + * @param int $height + */ + protected function setSpecificationSize(ImageSpecification $imageSpec, $width, $height) + { + $imageSpec->setResizeMode(ImageSpecification::RESIZE_MODE_INBOUND_FIXEDRATIO); + $imageSpec->setDimensions($width, $height); + } + + /** + * @param File $file + * @param $imageSpec + * @return string + * @throws \MediaAlchemyst\Exception\FileNotFoundException + */ + protected function resizeMediaFile(File $file, $imageSpec) + { + $tmp = tempnam(sys_get_temp_dir(), 'tmpdatabox') . '.jpg'; + $this->alchemyst->turninto($file->getPathname(), $tmp, $imageSpec); + + return $tmp; + } + + /** + * @param string $target + * @param string $filename + */ + protected function copyFile($target, $filename) + { + if (is_file($target)) { + $this->filesystem->remove($target); + } + + if (null === $target || null === $filename) { + return; + } + + $this->filesystem->mkdir(dirname($target), 0750); + $this->filesystem->copy($filename, $target, true); + $this->filesystem->chmod($target, 0760); + } +} diff --git a/lib/Alchemy/Phrasea/Core/Thumbnail/CollectionThumbnailManager.php b/lib/Alchemy/Phrasea/Core/Thumbnail/CollectionThumbnailManager.php new file mode 100644 index 0000000000..8c71a8b27a --- /dev/null +++ b/lib/Alchemy/Phrasea/Core/Thumbnail/CollectionThumbnailManager.php @@ -0,0 +1,69 @@ +validateFileMimeType($file); + $filename = $this->generateThumbnail($thumbnailType, $file); + } + + $logoFile = $this->rootPath . '/config/' . $thumbnailType . '/' . $element->getRootIdentifier(); + $custom_path = $this->rootPath . '/www/custom/' . $thumbnailType . '/' . $element->getRootIdentifier(); + + foreach ([$logoFile, $custom_path] as $target) { + $this->copyFile($target, $filename); + } + + $element->updateThumbnail($thumbnailType, $file); + } + + + /** + * @param $thumbnailType + * @param File $file + * @return string + */ + protected function generateThumbnail($thumbnailType, File $file) + { + $filename = $file->getPathname(); + $imageSpec = new ImageSpecification(); + + if ($thumbnailType === ThumbnailManager::TYPE_LOGO) { + //resize collection logo + $media = $this->application->getMediaFromUri($filename); + + if ($this->shouldResize($media, 120, 24)) { + $this->setSpecificationSize($imageSpec, 120, 24); + } + + $filename = $this->resizeMediaFile($file, $imageSpec); + + return $filename; + } elseif ($thumbnailType === ThumbnailManager::TYPE_PRESENTATION) { + //resize collection logo + $this->setSpecificationSize($imageSpec, 650, 200); + + $filename = $this->resizeMediaFile($file, $imageSpec); + + return $filename; + } + + return $filename; + } +} diff --git a/lib/Alchemy/Phrasea/Core/Thumbnail/DataboxThumbnailManager.php b/lib/Alchemy/Phrasea/Core/Thumbnail/DataboxThumbnailManager.php new file mode 100644 index 0000000000..00bf5da5fe --- /dev/null +++ b/lib/Alchemy/Phrasea/Core/Thumbnail/DataboxThumbnailManager.php @@ -0,0 +1,48 @@ +validateFileMimeType($file); + $filename = $this->generateThumbnail($file); + } + + $logoFile = $this->rootPath . '/config/minilogos/' . $thumbnailType . '_' . $element->getRootIdentifier() . '.jpg'; + $custom_path = $this->rootPath . '/www/custom/minilogos/' . $thumbnailType . '_' . $element->getRootIdentifier() . '.jpg'; + + foreach ([$logoFile, $custom_path] as $target) { + $this->copyFile($target, $filename); + } + + $element->updateThumbnail($thumbnailType, $file); + } + + /** + * @param File $file + * @return string + */ + protected function generateThumbnail(File $file) + { + $imageSpec = new ImageSpecification(); + + $this->setSpecificationSize($imageSpec, 120, 35); + + $filename = $this->resizeMediaFile($file, $imageSpec); + + return $filename; + } +} diff --git a/lib/Alchemy/Phrasea/Core/Thumbnail/ThumbnailManager.php b/lib/Alchemy/Phrasea/Core/Thumbnail/ThumbnailManager.php new file mode 100644 index 0000000000..f778b77416 --- /dev/null +++ b/lib/Alchemy/Phrasea/Core/Thumbnail/ThumbnailManager.php @@ -0,0 +1,21 @@ +app, + $alchemyst, + $filesystem, + $this->app['root.path'] + ); - if (!is_null($pathfile)) { - - if (!in_array(mb_strtolower($pathfile->getMimeType()), ['image/gif', 'image/png', 'image/jpeg', 'image/jpg', 'image/pjpeg'])) { - throw new \InvalidArgumentException('Invalid file format'); - } - - $filename = $pathfile->getPathname(); - - if ($pic_type === collection::PIC_LOGO) { - //resize collection logo - $imageSpec = new ImageSpecification(); - - $media = $this->app->getMediaFromUri($filename); - - if ($media->getWidth() > 120 || $media->getHeight() > 24) { - $imageSpec->setResizeMode(ImageSpecification::RESIZE_MODE_INBOUND_FIXEDRATIO); - $imageSpec->setDimensions(120, 24); - } - - $tmp = tempnam(sys_get_temp_dir(), 'tmpdatabox') . '.jpg'; - - try { - $alchemyst->turninto($pathfile->getPathname(), $tmp, $imageSpec); - $filename = $tmp; - } catch (\MediaAlchemyst\Exception $e) { - - } - } elseif ($pic_type === collection::PIC_PRESENTATION) { - //resize collection logo - $imageSpec = new ImageSpecification(); - $imageSpec->setResizeMode(ImageSpecification::RESIZE_MODE_INBOUND_FIXEDRATIO); - $imageSpec->setDimensions(650, 200); - - $tmp = tempnam(sys_get_temp_dir(), 'tmpdatabox') . '.jpg'; - - try { - $alchemyst->turninto($pathfile->getPathname(), $tmp, $imageSpec); - $filename = $tmp; - } catch (\MediaAlchemyst\Exception $e) { - - } - } - } - - switch ($pic_type) { - case collection::PIC_WM; - $collection->reset_watermark(); - break; - case collection::PIC_LOGO: - case collection::PIC_PRESENTATION: - break; - case collection::PIC_STAMP: - $collection->reset_stamp(); - break; - default: - throw new \InvalidArgumentException('unknown pic_type'); - break; - } - - if ($pic_type == collection::PIC_LOGO) { - $collection->update_logo($pathfile); - } - - $file = $this->app['root.path'] . '/config/' . $pic_type . '/' . $collection->get_base_id(); - $custom_path = $this->app['root.path'] . '/www/custom/' . $pic_type . '/' . $collection->get_base_id(); - - foreach ([$file, $custom_path] as $target) { - - if (is_file($target)) { - - $filesystem->remove($target); - } - - if (null === $target || null === $filename) { - continue; - } - - $filesystem->mkdir(dirname($target), 0750); - $filesystem->copy($filename, $target, true); - $filesystem->chmod($target, 0760); - } + $manager->setThumbnail($collection, $pic_type, $pathfile); return $this; } public function write_databox_pic(Alchemyst $alchemyst, Filesystem $filesystem, databox $databox, SymfoFile $pathfile = null, $pic_type) { - $filename = null; + $manager = new \Alchemy\Phrasea\Core\Thumbnail\DataboxThumbnailManager( + $this->app, + $alchemyst, + $filesystem, + $this->app['root.path'] + ); - if (!is_null($pathfile)) { - - if (!in_array(mb_strtolower($pathfile->getMimeType()), ['image/jpeg', 'image/jpg', 'image/pjpeg', 'image/png', 'image/gif'])) { - throw new \InvalidArgumentException('Invalid file format'); - } - } - - if (!in_array($pic_type, [databox::PIC_PDF])) { - throw new \InvalidArgumentException('unknown pic_type'); - } - - if ($pathfile) { - - $filename = $pathfile->getPathname(); - - $imageSpec = new ImageSpecification(); - $imageSpec->setResizeMode(ImageSpecification::RESIZE_MODE_INBOUND_FIXEDRATIO); - $imageSpec->setDimensions(120, 35); - - $tmp = tempnam(sys_get_temp_dir(), 'tmpdatabox') . '.jpg'; - - try { - $alchemyst->turninto($pathfile->getPathname(), $tmp, $imageSpec); - $filename = $tmp; - } catch (\MediaAlchemyst\Exception $e) { - - } - } - - $file = $this->app['root.path'] . '/config/minilogos/' . $pic_type . '_' . $databox->get_sbas_id() . '.jpg'; - $custom_path = $this->app['root.path'] . '/www/custom/minilogos/' . $pic_type . '_' . $databox->get_sbas_id() . '.jpg'; - - foreach ([$file, $custom_path] as $target) { - - if (is_file($target)) { - $filesystem->remove($target); - } - - if (is_null($filename)) { - continue; - } - - $filesystem->mkdir(dirname($target)); - $filesystem->copy($filename, $target); - $filesystem->chmod($target, 0760); - } - - $databox->delete_data_from_cache('printLogo'); + $manager->setThumbnail($databox, $pic_type, $pathfile); return $this; } diff --git a/lib/classes/collection.php b/lib/classes/collection.php index 1a21b490c8..d3c7516f10 100644 --- a/lib/classes/collection.php +++ b/lib/classes/collection.php @@ -14,11 +14,14 @@ use Alchemy\Phrasea\Core\Event\Collection\CollectionEvent; use Alchemy\Phrasea\Core\Event\Collection\CollectionEvents; use Alchemy\Phrasea\Core\Event\Collection\CreatedEvent; use Alchemy\Phrasea\Core\Event\Collection\NameChangedEvent; +use Alchemy\Phrasea\Core\Thumbnail\ThumbnailedElement; +use Alchemy\Phrasea\Core\Thumbnail\ThumbnailManager; use Alchemy\Phrasea\Exception\InvalidArgumentException; use Alchemy\Phrasea\Model\Entities\User; use Doctrine\DBAL\Driver\Connection; +use Symfony\Component\HttpFoundation\File\File; -class collection implements cache_cacheableInterface +class collection implements cache_cacheableInterface, ThumbnailedElement { protected $base_id; protected $sbas_id; @@ -227,6 +230,31 @@ class collection implements cache_cacheableInterface return $this->databox->get_connection(); } + public function getRootIdentifier() + { + return $this->base_id; + } + + public function updateThumbnail($thumbnailType, File $file = null) + { + switch ($thumbnailType) { + case ThumbnailManager::TYPE_WM; + $this->reset_watermark(); + break; + case ThumbnailManager::TYPE_LOGO: + $this->update_logo($file); + break; + case ThumbnailManager::TYPE_PRESENTATION: + break; + case ThumbnailManager::TYPE_STAMP: + $this->reset_stamp(); + break; + default: + throw new \InvalidArgumentException('Unsupported thumbnail type.'); + } + } + + public function set_public_presentation($publi) { if (in_array($publi, ['none', 'wm', 'stamp'])) { diff --git a/lib/classes/databox.php b/lib/classes/databox.php index e554b865af..9c5d4aa137 100644 --- a/lib/classes/databox.php +++ b/lib/classes/databox.php @@ -20,22 +20,34 @@ use Alchemy\Phrasea\Status\StatusStructureFactory; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Driver\Statement; use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\HttpFoundation\File\File; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Translation\TranslatorInterface; use Alchemy\Phrasea\Core\PhraseaTokens; -class databox extends base +class databox extends base implements \Alchemy\Phrasea\Core\Thumbnail\ThumbnailedElement { - /** @var int */ - protected $id; - /** @var string */ - protected $structure; + + const BASE_TYPE = self::DATA_BOX; + const CACHE_META_STRUCT = 'meta_struct'; + const CACHE_THESAURUS = 'thesaurus'; + const CACHE_COLLECTIONS = 'collections'; + const CACHE_STRUCTURE = 'structure'; + const PIC_PDF = 'logopdf'; + /** @var array */ protected static $_xpath_thesaurus = []; /** @var array */ protected static $_dom_thesaurus = []; /** @var array */ protected static $_thesaurus = []; + /** @var SimpleXMLElement */ + protected static $_sxml_thesaurus = []; + + /** @var int */ + protected $id; + /** @var string */ + protected $structure; /** @var array */ protected $_xpath_structure; /** @var DOMDocument */ @@ -48,16 +60,8 @@ class databox extends base protected $meta_struct; /** @var databox_subdefsStructure */ protected $subdef_struct; - /** @var SimpleXMLElement */ - protected static $_sxml_thesaurus = []; - - const BASE_TYPE = self::DATA_BOX; - const CACHE_META_STRUCT = 'meta_struct'; - const CACHE_THESAURUS = 'thesaurus'; - const CACHE_COLLECTIONS = 'collections'; - const CACHE_STRUCTURE = 'structure'; - const PIC_PDF = 'logopdf'; + /** @var string[] */ private $labels = []; private $ord; private $viewname; @@ -132,6 +136,16 @@ class databox extends base return $this->app->getApplicationBox(); } + public function getRootIdentifier() + { + return $this->get_sbas_id(); + } + + public function updateThumbnail($thumbnailType, File $file = null) + { + $this->delete_data_from_cache('printLogo'); + } + /** * @return collection[] */