|
|
@@ -0,0 +1,152 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+declare(strict_types=1);
|
|
|
+
|
|
|
+namespace App\Service\File\Factory;
|
|
|
+
|
|
|
+use Liip\ImagineBundle\Binary\BinaryInterface;
|
|
|
+use Liip\ImagineBundle\Imagine\Filter\FilterManager;
|
|
|
+
|
|
|
+class ImageFactory
|
|
|
+{
|
|
|
+ const RELATIVE_WIDTH_CROP_FILTER = 'relative_width_crop_filter';
|
|
|
+ const RELATIVE_WIDTH_FILTER = 'relative_width_filter';
|
|
|
+ const RELATIVE_HEIGHT_CROP_FILTER = 'relative_height_crop_filter';
|
|
|
+ const RELATIVE_HEIGHT_FILTER = 'relative_height_filter';
|
|
|
+ const CROP_FILTER = 'crop_filter';
|
|
|
+ const NO_FILTER = 'no_filter';
|
|
|
+
|
|
|
+ public function __construct(
|
|
|
+ private FilterManager $filterManager
|
|
|
+){}
|
|
|
+ /**
|
|
|
+ * Permet de créer et retourner une image selon la configuration du $file et les params de resize
|
|
|
+ * @param BinaryInterface $binary
|
|
|
+ * @param $fileConfig
|
|
|
+ * @param $height
|
|
|
+ * @param $width
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ public function create(BinaryInterface $binary, $fileConfig, $height, $width): string{
|
|
|
+ $filter = $this->getFilterType(!empty($fileConfig), $height, $width);
|
|
|
+ $filters_options = $this->getFiltersOptions($filter, $fileConfig, $height, $width);
|
|
|
+
|
|
|
+ //Si on a une config, on créer l'image
|
|
|
+ if($filters_options){
|
|
|
+ $filteredBinary = $this->filterManager->applyFilter($binary, $filter, ['filters' => $filters_options]);
|
|
|
+ $content = $filteredBinary->getContent();
|
|
|
+ }else{
|
|
|
+ $content = $binary->getContent();
|
|
|
+ }
|
|
|
+
|
|
|
+ return $content;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Définit le type de filtre à appliquer
|
|
|
+ * @param $cropConfigEnabled
|
|
|
+ * @param $params
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ private function getFilterType($cropConfigEnabled, $forcedHeight, $forcedWidth){
|
|
|
+ //Si les params sont présents, on souhaite une image avec une largeur ou hauteur spécifique
|
|
|
+ if($forcedHeight || $forcedWidth){
|
|
|
+ //A partir du moment ou l'un des params est > 0
|
|
|
+ if($forcedHeight > 0 || $forcedWidth > 0){
|
|
|
+ //Si la hauteur est nulle OU si la hateur et la largeur sont renseigné (on ne peux pas autoriser les deux
|
|
|
+ //car l'image serait déformée, donc on ne garde que la largeur dans ce dernier cas)
|
|
|
+ if($forcedHeight == 0 || ($forcedHeight > 0 && $forcedWidth > 0)){
|
|
|
+ $filter = $cropConfigEnabled ? self::RELATIVE_WIDTH_CROP_FILTER : self::RELATIVE_WIDTH_FILTER;
|
|
|
+ }
|
|
|
+ //Si la largeur est nulle
|
|
|
+ else if($forcedWidth == 0) {
|
|
|
+ $filter = $cropConfigEnabled ? self::RELATIVE_HEIGHT_CROP_FILTER : self::RELATIVE_HEIGHT_FILTER;
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ //Si les deux params sont <= 0 alors aucun filtre ne doit être appliqué
|
|
|
+ $filter = self::NO_FILTER;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //Sinon, si la configuration du crop est faite
|
|
|
+ else if($cropConfigEnabled){
|
|
|
+ $filter = self::CROP_FILTER;
|
|
|
+ }else{
|
|
|
+ //Enfin, aucun filtre ne doit être appliqué
|
|
|
+ $filter = self::NO_FILTER;
|
|
|
+ }
|
|
|
+ return $filter;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Construit les options des filtres à appliquer
|
|
|
+ * @param $params
|
|
|
+ */
|
|
|
+
|
|
|
+ private function getFiltersOptions($filter, $fileConfig, $forcedHeight, $forcedWidth){
|
|
|
+ switch ($filter){
|
|
|
+ case self::NO_FILTER:
|
|
|
+ return [];
|
|
|
+
|
|
|
+ case self::CROP_FILTER:
|
|
|
+ return $this->getCropFilterOptions($fileConfig);
|
|
|
+
|
|
|
+ case self::RELATIVE_WIDTH_CROP_FILTER:
|
|
|
+ return array_merge($this->getCropFilterOptions($fileConfig), $this->getRelativeWidhtFilterOptions($forcedWidth));
|
|
|
+
|
|
|
+ case self::RELATIVE_HEIGHT_CROP_FILTER:
|
|
|
+ return array_merge($this->getCropFilterOptions($fileConfig), $this->getRelativeHeightFilterOptions($forcedHeight));
|
|
|
+
|
|
|
+ case self::RELATIVE_HEIGHT_FILTER:
|
|
|
+ return $this->getRelativeHeightFilterOptions($forcedHeight);
|
|
|
+
|
|
|
+ case self::RELATIVE_WIDTH_FILTER:
|
|
|
+ return array_merge($this->getRelativeWidhtFilterOptions($forcedWidth));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Définit et retourne le tableau de config servant à cropper
|
|
|
+ * @param string $config : Configuration du File
|
|
|
+ * @return array<string, array<string, array<string, array<int, int>>>> : tableau de configuration
|
|
|
+ * @see ImageUtilsTest::testGetCroppingConfig()
|
|
|
+ */
|
|
|
+ protected function getCropFilterOptions(string $config): array{
|
|
|
+ $crop_filters_options = [];
|
|
|
+ $config = json_decode($config, true);
|
|
|
+
|
|
|
+ //On s'assure que la hauteur ET la largeur soient > 0
|
|
|
+ if($config['width'] > 0 && $config['height'] > 0){
|
|
|
+ $crop_filters_options = array_merge(
|
|
|
+ [
|
|
|
+ 'crop' => array(
|
|
|
+ 'size' => [intval($config['width']), intval($config['height'])],
|
|
|
+ 'start' => [intval($config['x']), intval($config['y'])]
|
|
|
+ )
|
|
|
+ ]
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return $crop_filters_options;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Construit les options pour le filtre gérant la largeur relative
|
|
|
+ * @param $forcedWidth
|
|
|
+ * @return array[]
|
|
|
+ */
|
|
|
+ private function getRelativeWidhtFilterOptions($forcedWidth){
|
|
|
+ return ['relative_resize' => array(
|
|
|
+ 'widen' => intval($forcedWidth)
|
|
|
+ )];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Construit les options pour le filtre gérant la hauteur relative
|
|
|
+ * @param $forcedHeight
|
|
|
+ * @return array[]
|
|
|
+ */
|
|
|
+ private function getRelativeHeightFilterOptions($forcedHeight){
|
|
|
+ return ['relative_resize' => array(
|
|
|
+ 'heighten' => intval($forcedHeight)
|
|
|
+ )];
|
|
|
+ }
|
|
|
+}
|