src/AtechNet/CoreBundle/Helper/Furbify/Image.php line 385

Open in your IDE?
  1. <?php
  2. namespace App\AtechNet\CoreBundle\Helper\Furbify;
  3. use App\AtechNet\CoreBundle\Entity\Photo;
  4. class Image
  5. {
  6.     private $filename;
  7.     private $image;
  8.     private $width;
  9.     private $height;
  10.     private $mimeType;
  11.     private $extension;
  12.     private $path;
  13.     private $urlImage;
  14.     private $dirImage;
  15.     private $dirCache;
  16.     private $placeholder;
  17.     private $photo;
  18.     private $directory;
  19.     private $cloudflare = true;
  20.     private $inlineCloudflare = false;
  21.     public const URL_CENTRALIS_IMAGE = 'https://www.atechcomp.eu/centralis/web/';
  22.     public const URL_CENTRALIS_IMAGE_LOCAL = 'https://centralis/';
  23.     public const URL_IMAGE = '/storage/image/';
  24.     public const DIR_IMAGE = '/../../Resources/storage/private/image/';
  25.     public const DIR_CACHE = '/../../Resources/storage/public/image/cache/';
  26.     public const PLACEHOLDER = '/../../Resources/storage/private/image/placeholder.png';
  27.     public const PRODUCT_VIEW_THUMB_WIDTH = 540;
  28.     public const PRODUCT_VIEW_THUMB_HEIGHT = 405;
  29.     public const PRODUCT_VIEW_ADDITIONAL_WIDTH = 120;
  30.     public const PRODUCT_VIEW_ADDITIONAL_HEIGHT = 90;
  31.     public const PRODUCT_VIEW_POPUP_WIDTH = 1000;
  32.     public const PRODUCT_VIEW_POPUP_HEIGHT = 750;
  33.     public const PRODUCT_LIST_THUMB_WIDTH = 278;
  34.     public const PRODUCT_LIST_THUMB_HEIGHT = 210;
  35.     public const PRODUCT_CART_THUMB_WIDTH = 60;
  36.     public const PRODUCT_CART_THUMB_HEIGHT = 45;
  37.     public const PRODUCT_CONFIGURATOR_ITEM_THUMB_WIDTH = 40;
  38.     public const PRODUCT_CONFIGURATOR_ITEM_THUMB_HEIGHT = 30;
  39.     public const BLOG_BLOCK_THUMB_WIDTH = 540;
  40.     public const BLOG_BLOCK_THUMB_HEIGHT = 405;
  41.     public const BLOG_BLOCK_ADDITIONAL_WIDTH = 100;
  42.     public const BLOG_BLOCK_ADDITIONAL_HEIGHT = 75;
  43.     public const BLOG_LIST_THUMB_WIDTH = 220;
  44.     public const BLOG_LIST_THUMB_HEIGHT = 220;
  45.     public const BLOG_BLOCK_THUMB_16_9_WIDTH = 540;
  46.     public const BLOG_BLOCK_THUMB_16_9_HEIGHT = 304;
  47.     public const BLOG_BLOCK_THUMB_730_WIDTH = 365;
  48.     public const BLOG_BLOCK_THUMB_300_HEIGHT = 206;
  49.     public const BANNER_DESKTOP_WIDTH = 820;
  50.     public const BANNER_DESKTOP_HEIGHT = 340;
  51.     public const BANNER_MOBILE_WIDTH = 768;
  52.     public const BANNER_MOBILE_HEIGHT = 360;
  53.     public const SMALL_BANNER_DESKTOP_WIDTH = 550;
  54.     public const SMALL_BANNER_DESKTOP_HEIGHT = 244;
  55.     public const HEADER_FEATURED_CATEGORY_WIDTH = 360;
  56.     public const HEADER_FEATURED_CATEGORY_HEIGHT = 160;
  57.     public const SOCIAL_MEDIA_IMAGE_WIDTH = 1920;
  58.     public const SOCIAL_MEDIA_IMAGE_HEIGHT = 1080;
  59.     public const TESTIMONIAL_THUMB_WIDTH = 180;
  60.     public const TESTIMONIAL_THUMB_HEIGHT = 180;
  61.     public const LIVESEARCH_THUMB_WIDTH = 80;
  62.     public const LIVESEARCH_THUMB_HEIGHT = 60;
  63.     /**
  64.      * Image constructor.
  65.      * @param array $cloudFlareImageApiConfig
  66.      * @param object|string|array<string,string> $photo
  67.      * @param string $directory
  68.      * @param bool|null $overwrite
  69.      */
  70.     public function __construct(array $cloudFlareImageApiConfig, $photo, $directory = 'product', ?bool $overwrite = null)
  71.     {
  72.         // Photo
  73.         $this->photo = $photo;
  74.         // Directory
  75.         $this->directory = $directory;
  76.         // Cloudflare
  77.         $this->cloudflareConfig = $cloudFlareImageApiConfig;
  78.         if ((int)$this->cloudflareConfig['active'] == 1) {
  79.             $this->setCloudflare(true);
  80.         } else {
  81.             $this->setCloudflare(false);
  82.         }
  83.         if (!(is_object($photo) && !empty($photo->getCloudflareId()))) {
  84.             $this->setCloudflare(false);
  85.         }
  86.         $this->setInlineCloudflare(false);
  87.         if (!is_null($overwrite)) {
  88.             $this->setCloudflare($overwrite);
  89.             $this->setInlineCloudflare($overwrite);
  90.         }
  91.         // Serve image via the old method
  92.         if (!$this->isCloudflare()) {
  93.             // GD
  94.             if (!extension_loaded('gd')) {
  95.                 exit('Error: PHP GD is not installed!');
  96.             }
  97.             // Default Directories
  98.             $this->dirImage = __DIR__ . self::DIR_IMAGE;
  99.             $this->dirCache = __DIR__ . self::DIR_CACHE;
  100.             $this->placeholder = __DIR__ . self::PLACEHOLDER;
  101.             // Image URL
  102.             $this->urlImage = (((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443) ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . self::URL_IMAGE;
  103.             // Path
  104.             $this->path = '';
  105.             // Create Target Directory
  106.             if ($directory != '') {
  107.                 $directories = explode('/', $directory);
  108.                 foreach ($directories as $d) {
  109.                     $this->path .= $d . DIRECTORY_SEPARATOR;
  110.                     if (!is_dir($this->dirCache . $this->path)) {
  111.                         mkdir($this->dirCache . $this->path, 0755);
  112.                     }
  113.                     if (!is_dir($this->dirImage . $this->path)) {
  114.                         mkdir($this->dirImage . $this->path, 0755);
  115.                     }
  116.                 }
  117.             }
  118.             /**
  119.              * @var Photo $photo
  120.              */
  121.             if (is_object($photo)) {
  122.                 // Image Path
  123.                 $photo_full_path = $this->dirImage . $this->path . $photo->getOriginalName();
  124.                 // Download Photo from Centralis
  125.                 if (!file_exists($photo_full_path)) {
  126.                     $centralisSource = @file_get_contents(self::URL_CENTRALIS_IMAGE . $this->photo->getContextWebPath('eshop'));
  127.                     if ($centralisSource) {
  128.                         file_put_contents($photo_full_path, $centralisSource);
  129.                     }
  130.                 }
  131.                 // Image - gif
  132.                 if ($photo->getMimeType() == 'image/gif') {
  133.                     if (file_exists($photo_full_path)) {
  134.                         $this->image = imagecreatefromgif($photo_full_path);
  135.                         $info = getimagesize($photo_full_path);
  136.                         $this->width = $info[0];
  137.                         $this->height = $info[1];
  138.                         $this->mimeType = $photo->getMimeType();
  139.                         $this->filename = $this->getFilenameWithoutExtension($photo->getOriginalName());
  140.                         $this->extension = 'gif';
  141.                     }
  142.                 }
  143.                 // Image - png
  144.                 elseif ($photo->getMimeType() == 'image/png') {
  145.                     if (file_exists($photo_full_path)) {
  146.                         $this->image = imagecreatefrompng($photo_full_path);
  147.                         $info = getimagesize($photo_full_path);
  148.                         $this->width = $info[0];
  149.                         $this->height = $info[1];
  150.                         $this->mimeType = $photo->getMimeType();
  151.                         $this->filename = $this->getFilenameWithoutExtension($photo->getOriginalName());
  152.                         $this->extension = 'png';
  153.                     }
  154.                 }
  155.                 // Image - jpeg
  156.                 elseif ($photo->getMimeType() == 'image/jpeg' || $photo->getMimeType() == 'image/jpg') {
  157.                     if (file_exists($photo_full_path)) {
  158.                         $this->image = imagecreatefrompng($photo_full_path);
  159.                         $info = getimagesize($photo_full_path);
  160.                         $this->width = $info[0];
  161.                         $this->height = $info[1];
  162.                         $this->mimeType = $photo->getMimeType();
  163.                         $this->filename = $this->getFilenameWithoutExtension($photo->getOriginalName());
  164.                         $this->extension = 'jpg';
  165.                     }
  166.                 }
  167.                 // Image - webp
  168.                 else if ($photo->getMimeType() == 'image/webp') {
  169.                     if (file_exists($photo_full_path)) {
  170.                         $this->image = imagecreatefromwebp($photo_full_path);
  171.                         $info = getimagesize($photo_full_path);
  172.                         $this->width = $info[0];
  173.                         $this->height = $info[1];
  174.                         $this->mimeType = $photo->getMimeType();
  175.                         $this->filename = $this->getFilenameWithoutExtension($photo->getOriginalName());
  176.                         $this->extension = 'webp';
  177.                     }
  178.                 }
  179.             }
  180.             // Physical Photo
  181.             elseif (is_string($photo) || is_array($photo)) {
  182.                 // Download blog cover from centralis
  183.                 if ($directory == 'blog') {
  184.                     if (!file_exists($this->dirImage . $this->path . basename($photo))) {
  185.                         $centralisSource = @file_get_contents($photo);
  186.                         if ($centralisSource) {
  187.                             file_put_contents($this->dirImage . $this->path . basename($photo), $centralisSource);
  188.                         }
  189.                     }
  190.                 } elseif (is_array($photo) && $directory == 'banners') {
  191.                     if (!file_exists($this->dirImage . $this->path . basename($photo['originalName']))) {
  192.                         $centralisSource = @file_get_contents(self::URL_CENTRALIS_IMAGE . 'uploads/banners/' . $photo['filename']);
  193.                         if ($centralisSource) {
  194.                             file_put_contents($this->dirImage . $this->path . basename($photo['originalName']), $centralisSource);
  195.                         }
  196.                     }
  197.                     $photo = $photo['originalName'];
  198.                 } elseif (is_array($photo) && $directory == 'category-group-member-image') {
  199.                     if (!file_exists($this->dirImage . $this->path . basename($photo['filename']))) {
  200.                         $centralisSource = @file_get_contents(self::URL_CENTRALIS_IMAGE . 'uploads/category-group-member-image/' . $photo['filename']);
  201.                         if ($centralisSource) {
  202.                             file_put_contents($this->dirImage . $this->path . basename($photo['filename']), $centralisSource);
  203.                         }
  204.                     }
  205.                     $photo = $photo['filename'];
  206.                 } elseif (is_array($photo) && $directory == 'social_media_images') {
  207.                     if (!file_exists($this->dirImage . $this->path . basename($photo['originalName']))) {
  208.                         $centralisSource = file_get_contents(self::URL_CENTRALIS_IMAGE . $photo['centralisDirectory'] . $photo['originalName']);
  209.                         if ($centralisSource) {
  210.                             file_put_contents($this->dirImage . $this->path . basename($photo['originalName']), $centralisSource);
  211.                         }
  212.                     }
  213.                     $photo = $photo['originalName'];
  214.                 }
  215.                 // Ge file name from URL
  216.                 if (substr($photo, 0, 4) == 'http') {
  217.                     $photo = basename($photo);
  218.                 }
  219.                 if (file_exists($this->dirImage . $this->path . $photo)) {
  220.                     $info = getimagesize($this->dirImage . $this->path . $photo);
  221.                     $this->width = $info[0];
  222.                     $this->height = $info[1];
  223.                     $this->mimeType = isset($info['mime']) ? $info['mime'] : '';
  224.                     // Get Filename without extension
  225.                     $this->filename = $this->getFilenameWithoutExtension($photo);
  226.                     if ($this->mimeType == 'image/gif') {
  227.                         $this->image = imagecreatefromgif($this->dirImage . $this->path . $photo);
  228.                         $this->extension = 'gif';
  229.                     } elseif ($this->mimeType == 'image/png') {
  230.                         $this->image = imagecreatefrompng($this->dirImage . $this->path . $photo);
  231.                         $this->extension = 'png';
  232.                     } elseif ($this->mimeType == 'image/jpeg' || $this->mimeType == 'image/jpg') {
  233.                         $this->image = imagecreatefromjpeg($this->dirImage . $this->path . $photo);
  234.                         $this->extension = 'jpg';
  235.                         if (pathinfo($photo, PATHINFO_EXTENSION) == 'jpeg') {
  236.                             $this->extension = 'jpeg';
  237.                         }
  238.                     }
  239.                     else if ($this->mimeType == 'image/webp') {
  240.                         $this->image = imagecreatefromwebp($this->dirImage . $this->path . $photo);
  241.                         $this->extension = 'webp';
  242.                     }
  243.                 }
  244.             }
  245.             // Placeholder
  246.             if (!$this->image instanceof \GdImage) {
  247.                 if (file_exists($this->placeholder)) {
  248.                     $this->image = imagecreatefrompng($this->placeholder);
  249.                     $info = getimagesize($this->placeholder);
  250.                     $this->width = $info[0];
  251.                     $this->height = $info[1];
  252.                     $this->mimeType = 'image/png';
  253.                     $this->path = '';
  254.                     $this->filename = 'placeholder';
  255.                     $this->extension = 'png';
  256.                 }
  257.             }
  258.             if (!$this->image instanceof \GdImage) {
  259.                 exit('Error: Could not load image!');
  260.             }
  261.         }
  262.     }
  263.     /**
  264.      * @param bool $status
  265.      */
  266.     public function setCloudflare(bool $status): void
  267.     {
  268.         $this->cloudflare = $status;
  269.     }
  270.     /**
  271.      * @return bool
  272.      */
  273.     public function isCloudflare(): bool
  274.     {
  275.         return $this->cloudflare;
  276.     }
  277.     /**
  278.      * @param bool $inline
  279.      */
  280.     public function setInlineCloudflare(bool $inline): void
  281.     {
  282.         $this->inlineCloudflare = $inline;
  283.     }
  284.     /**
  285.      * @return bool
  286.      */
  287.     public function isCloudflareInline(): bool
  288.     {
  289.         return $this->inlineCloudflare;
  290.     }
  291.     /**
  292.      * @param int $width
  293.      * @param int $height
  294.      * @return string
  295.      */
  296.     public function resize(int $width, int $height): string
  297.     {
  298.         // Serve Image via Cloudflare
  299.         if ($this->isCloudflare()) {
  300.             $cloudflareVariant = self::determineCloudflareVariant($width, $height);
  301.             if (!is_null($cloudflareVariant)) {
  302.                 // Inline
  303.                 if ($this->isCloudflareInline()) {
  304.                     return $this->photo->getInlineUrl($width, $height);
  305.                 }
  306.                 return $this->photo->getCdnUrl($cloudflareVariant);
  307.             }
  308.             // Otherwise serve image via the old method
  309.             return ( new Image($this->cloudflareConfig, $this->photo, $this->directory, false) )->resize($width, $height);
  310.         }
  311.         // Serve image via the old method
  312.         $image_old = $this->filename . '.' . $this->extension;
  313.         $image_old_full_path = $this->dirImage . $this->path . $image_old;
  314.         $image_new = $this->filename . '-' . (int)$width . 'x' . (int)$height . '.' . $this->extension;
  315.         $image_new_full_path = $this->dirCache . $this->path . $image_new;
  316.         if (!is_file($image_new_full_path) || (@filemtime($image_old_full_path) > @filemtime($image_new_full_path))) {
  317.             if ($this->width != $width || $this->height != $height) {
  318.                 $scale_w = $width / $this->width;
  319.                 $scale_h = $height / $this->height;
  320.                 $scale = min($scale_w, $scale_h);
  321.                 $new_width = (int)($this->width * $scale);
  322.                 $new_height = (int)($this->height * $scale);
  323.                 $xpos = (int)(($width - $new_width) / 2);
  324.                 $ypos = (int)(($height - $new_height) / 2);
  325.                 $image = $this->image;
  326.                 $this->image = imagecreatetruecolor($width, $height);
  327.                 if ($this->mimeType == 'image/png') {
  328.                     imagealphablending($this->image, false);
  329.                     imagesavealpha($this->image, true);
  330.                     $background = imagecolorallocatealpha($this->image, 255, 255, 255, 127);
  331.                     imagecolortransparent($this->image, $background);
  332.                 } else {
  333.                     $background = imagecolorallocate($this->image, 255, 255, 255);
  334.                 }
  335.                 imagefilledrectangle($this->image, 0, 0, $width, $height, $background);
  336.                 imagecopyresampled($this->image, $image, $xpos, $ypos, 0, 0, $new_width, $new_height, $this->width, $this->height);
  337.                 imagedestroy($image);
  338.                 if ($this->image instanceof \GdImage) {
  339.                     if ($this->extension == 'jpeg' || $this->extension == 'jpg') {
  340.                         imagejpeg($this->image, $image_new_full_path, 90);
  341.                     } elseif ($this->extension == 'png') {
  342.                         imagepng($this->image, $image_new_full_path);
  343.                     } elseif ($this->extension == 'gif') {
  344.                         imagegif($this->image, $image_new_full_path);
  345.                     }elseif ($this->extension == 'webp') {
  346.                         imagewebp($this->image, $image_new_full_path);
  347.                     }
  348.                     imagedestroy($this->image);
  349.                 }
  350.             } else {
  351.                 @copy($image_old_full_path, $image_new_full_path);
  352.             }
  353.         }
  354.         return $this->urlImage . $this->path . $image_new;
  355.     }
  356.     private function getFilenameWithoutExtension($fullFilename)
  357.     {
  358.         return preg_replace('/\\.[^.\\s]{3,4}$/', '', $fullFilename);
  359.     }
  360.     /**
  361.      * @param int $width
  362.      * @param int $height
  363.      * @return string|null
  364.      */
  365.     public static function determineCloudflareVariant($width, $height): ?string
  366.     {
  367.         // ProductCartThumb
  368.         if ($width == self::PRODUCT_CART_THUMB_WIDTH && $height == self::PRODUCT_CART_THUMB_HEIGHT) {
  369.             return 'ProductCartThumb';
  370.         }
  371.         // ProductConfiguratorItemThumb
  372.         elseif ($width == self::PRODUCT_CONFIGURATOR_ITEM_THUMB_WIDTH && $height == self::PRODUCT_CONFIGURATOR_ITEM_THUMB_HEIGHT) {
  373.             return 'ProductConfiguratorItemThumb';
  374.         }
  375.         // ProductListThumb
  376.         elseif ($width == self::PRODUCT_LIST_THUMB_WIDTH && $height == self::PRODUCT_LIST_THUMB_HEIGHT) {
  377.             return 'ProductListThumb';
  378.         }
  379.         // ProductViewAdditional
  380.         elseif ($width == self::PRODUCT_VIEW_ADDITIONAL_WIDTH && $height == self::PRODUCT_VIEW_ADDITIONAL_HEIGHT) {
  381.             return 'ProductViewAdditional';
  382.         }
  383.         // ProductViewPop
  384.         elseif ($width == self::PRODUCT_VIEW_POPUP_WIDTH && $height == self::PRODUCT_VIEW_POPUP_HEIGHT) {
  385.             return 'ProductViewPop';
  386.         }
  387.         // ProductViewThumb
  388.         elseif ($width == self::PRODUCT_VIEW_THUMB_WIDTH && $height == self::PRODUCT_VIEW_THUMB_HEIGHT) {
  389.             return 'ProductViewThumb';
  390.         }
  391.     
  392.         // Empty
  393.         return null;
  394.     }
  395. }