appState = $appState; $this->imageConfig = $imageConfig; $this->productImage = $productImage; $this->imageFactory = $imageFactory; $this->paramsBuilder = $paramsBuilder; $this->viewConfig = $viewConfig; $this->assertImageFactory = $assertImageFactory; $this->themeCustomizationConfig = $themeCustomizationConfig; $this->themeCollection = $themeCollection; $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $this->filesystem = $filesystem; } /** * Create resized images of different sizes from an original image * @param string $originalImageName * @throws NotFoundException */ public function resizeFromImageName(string $originalImageName) { $originalImagePath = $this->mediaDirectory->getAbsolutePath( $this->imageConfig->getMediaPath($originalImageName) ); if (!$this->mediaDirectory->isFile($originalImagePath)) { throw new NotFoundException(__('Cannot resize image "%1" - original image not found', $originalImagePath)); } foreach ($this->getViewImages($this->getThemesInUse()) as $viewImage) { $this->resize($viewImage, $originalImagePath, $originalImageName); } } /** * Create resized images of different sizes from themes * @param array|null $themes * @return \Generator * @throws NotFoundException */ public function resizeFromThemes(array $themes = null): \Generator { $count = $this->productImage->getCountAllProductImages(); if (!$count) { throw new NotFoundException(__('Cannot resize images - product images not found')); } $productImages = $this->productImage->getAllProductImages(); $viewImages = $this->getViewImages($themes ?? $this->getThemesInUse()); foreach ($productImages as $image) { $originalImageName = $image['filepath']; $originalImagePath = $this->mediaDirectory->getAbsolutePath( $this->imageConfig->getMediaPath($originalImageName) ); foreach ($viewImages as $viewImage) { $this->resize($viewImage, $originalImagePath, $originalImageName); } yield $originalImageName => $count; } } /** * Search the current theme * @return array */ private function getThemesInUse(): array { $themesInUse = []; $registeredThemes = $this->themeCollection->loadRegisteredThemes(); $storesByThemes = $this->themeCustomizationConfig->getStoresByThemes(); $keyType = is_integer(key($storesByThemes)) ? 'getId' : 'getCode'; foreach ($registeredThemes as $registeredTheme) { if (array_key_exists($registeredTheme->$keyType(), $storesByThemes)) { $themesInUse[] = $registeredTheme; } } return $themesInUse; } /** * Get view images data from themes * @param array $themes * @return array */ private function getViewImages(array $themes): array { $viewImages = []; /** @var \Magento\Theme\Model\Theme $theme */ foreach ($themes as $theme) { $config = $this->viewConfig->getViewConfig([ 'area' => Area::AREA_FRONTEND, 'themeModel' => $theme, ]); $images = $config->getMediaEntities('Magento_Catalog', ImageHelper::MEDIA_TYPE_CONFIG_NODE); foreach ($images as $imageId => $imageData) { $uniqIndex = $this->getUniqueImageIndex($imageData); $imageData['id'] = $imageId; $viewImages[$uniqIndex] = $imageData; } } return $viewImages; } /** * Get unique image index * @param array $imageData * @return string */ private function getUniqueImageIndex(array $imageData): string { ksort($imageData); unset($imageData['type']); return md5(json_encode($imageData)); } /** * Make image * @param string $originalImagePath * @param array $imageParams * @return Image */ private function makeImage(string $originalImagePath, array $imageParams): Image { $image = $this->imageFactory->create($originalImagePath); $image->keepAspectRatio($imageParams['keep_aspect_ratio']); $image->keepFrame($imageParams['keep_frame']); $image->keepTransparency($imageParams['keep_transparency']); $image->constrainOnly($imageParams['constrain_only']); $image->backgroundColor($imageParams['background']); $image->quality($imageParams['quality']); return $image; } /** * Resize image * @param array $viewImage * @param string $originalImagePath * @param string $originalImageName */ private function resize(array $viewImage, string $originalImagePath, string $originalImageName) { $imageParams = $this->paramsBuilder->build($viewImage); $image = $this->makeImage($originalImagePath, $imageParams); $imageAsset = $this->assertImageFactory->create( [ 'miscParams' => $imageParams, 'filePath' => $originalImageName, ] ); if ($imageParams['image_width'] !== null && $imageParams['image_height'] !== null) { $image->resize($imageParams['image_width'], $imageParams['image_height']); } $image->save($imageAsset->getPath()); } }