Current File : //var/www/vinorea/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/Product/ImageController.php |
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to https://devdocs.prestashop.com/ for more information.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
*/
declare(strict_types=1);
namespace PrestaShopBundle\Controller\Admin\Sell\Catalog\Product;
use Exception;
use PrestaShop\PrestaShop\Adapter\Shop\Repository\ShopRepository;
use PrestaShop\PrestaShop\Core\Domain\Exception\FileUploadException;
use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductConstraintException;
use PrestaShop\PrestaShop\Core\Domain\Product\Image\Command\DeleteProductImageCommand;
use PrestaShop\PrestaShop\Core\Domain\Product\Image\Command\ProductImageSetting;
use PrestaShop\PrestaShop\Core\Domain\Product\Image\Command\SetProductImagesForAllShopCommand;
use PrestaShop\PrestaShop\Core\Domain\Product\Image\Exception\CannotAddProductImageException;
use PrestaShop\PrestaShop\Core\Domain\Product\Image\Exception\CannotRemoveCoverException;
use PrestaShop\PrestaShop\Core\Domain\Product\Image\Exception\ProductImageNotFoundException;
use PrestaShop\PrestaShop\Core\Domain\Product\Image\Query\GetProductImage;
use PrestaShop\PrestaShop\Core\Domain\Product\Image\Query\GetProductImages;
use PrestaShop\PrestaShop\Core\Domain\Product\Image\Query\GetShopProductImages;
use PrestaShop\PrestaShop\Core\Domain\Product\Image\QueryResult\ProductImage;
use PrestaShop\PrestaShop\Core\Domain\Product\Image\QueryResult\Shop\ShopImageAssociation;
use PrestaShop\PrestaShop\Core\Domain\Product\Image\QueryResult\Shop\ShopProductImagesCollection;
use PrestaShop\PrestaShop\Core\Domain\Shop\ValueObject\ShopConstraint;
use PrestaShop\PrestaShop\Core\Domain\Shop\ValueObject\ShopId;
use PrestaShop\PrestaShop\Core\Exception\CoreException;
use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilderInterface;
use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandlerInterface;
use PrestaShop\PrestaShop\Core\Image\Exception\CannotUnlinkImageException;
use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\MemoryLimitException;
use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\UploadedImageConstraintException;
use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\UploadedImageSizeException;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use PrestaShopBundle\Entity\Shop;
use PrestaShopBundle\Security\Annotation\AdminSecurity;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class ImageController extends FrameworkBundleAdminController
{
/**
* Retrieves images for all shops, but the cover (which is multi-shop compatable) is retrieved based on $shopId
*
* @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", message="You do not have permission to update this.")
*
* @param int $productId
* @param int $shopId
*
* @return JsonResponse
*/
public function getImagesForShopAction(int $productId, int $shopId): JsonResponse
{
/** @var ProductImage[] $images */
$images = $this->getQueryBus()->handle(new GetProductImages(
$productId,
ShopConstraint::shop($shopId)
));
return $this->json(array_map([$this, 'formatImage'], $images));
}
/**
* @AdminSecurity("is_granted('read', request.get('_legacy_controller')) || is_granted('update', request.get('_legacy_controller'))", message="You do not have permission to red or update this.")
*
* @param int $productId
*
* @return JsonResponse
*/
public function productShopImagesAction(int $productId, Request $request): JsonResponse
{
if ($request->isMethod(Request::METHOD_POST)) {
try {
$imageAssociations = json_decode($request->request->get('image_associations'), true);
$command = new SetProductImagesForAllShopCommand($productId);
foreach ($imageAssociations as $imageAssociation) {
$command->addProductSetting(new ProductImageSetting(
$imageAssociation['imageId'],
$imageAssociation['shops']
));
}
$this->getQueryBus()->handle($command);
} catch (CoreException $e) {
return $this->json([
'status' => false,
'message' => $this->getErrorMessageForException($e, $this->getErrorMessages($e)),
]);
}
}
return $this->getProductShopImagesJsonResponse($productId);
}
/**
* @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", message="You do not have permission to update this.")
*
* @param Request $request
*
* @return JsonResponse
*/
public function addImageAction(Request $request): JsonResponse
{
$imageForm = $this->getProductImageFormBuilder()->getForm();
$imageForm->handleRequest($request);
try {
$result = $this->getProductImageFormHandler()->handle($imageForm);
if (!$result->isSubmitted() || !$result->isValid()) {
return new JsonResponse([
'error' => 'Invalid form data.',
'form_errors' => $this->getFormErrorsForJS($imageForm),
], Response::HTTP_BAD_REQUEST);
}
if (null === $result->getIdentifiableObjectId()) {
return new JsonResponse([
'error' => 'Could not create image.',
], Response::HTTP_BAD_REQUEST);
}
} catch (Exception $e) {
return new JsonResponse([
'error' => $this->getErrorMessageForException($e, $this->getErrorMessages($e)),
], Response::HTTP_BAD_REQUEST);
}
return $this->getProductImageJsonResponse($result->getIdentifiableObjectId());
}
/**
* @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", message="You do not have permission to update this.")
*
* @param Request $request
* @param int $productImageId
*
* @return JsonResponse
*/
public function updateImageAction(Request $request, int $productImageId): JsonResponse
{
$imageForm = $this->getProductImageFormBuilder()->getFormFor($productImageId, [], [
'method' => $request->getMethod(),
]);
$imageForm->handleRequest($request);
try {
$result = $this->getProductImageFormHandler()->handleFor($productImageId, $imageForm);
if (!$result->isSubmitted() || !$result->isValid()) {
return new JsonResponse([
'error' => 'Invalid form data.',
'form_errors' => $this->getFormErrorsForJS($imageForm),
], Response::HTTP_BAD_REQUEST);
}
} catch (Exception $e) {
return new JsonResponse([
'error' => $this->getErrorMessageForException($e, $this->getErrorMessages($e)),
], Response::HTTP_BAD_REQUEST);
}
return $this->getProductImageJsonResponse($productImageId);
}
/**
* @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", message="You do not have permission to update this.")
*
* @param int $productImageId
*
* @return JsonResponse
*/
public function deleteImageAction(int $productImageId): JsonResponse
{
try {
$this->getCommandBus()->handle(new DeleteProductImageCommand($productImageId));
} catch (Exception $e) {
return new JsonResponse([
'error' => $this->getErrorMessageForException($e, $this->getErrorMessages($e)),
], Response::HTTP_BAD_REQUEST);
}
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
}
/**
* @return FormBuilderInterface
*/
private function getProductImageFormBuilder(): FormBuilderInterface
{
return $this->get('prestashop.core.form.identifiable_object.builder.product_image_form_builder');
}
/**
* @return FormHandlerInterface
*/
private function getProductImageFormHandler(): FormHandlerInterface
{
return $this->get('prestashop.core.form.identifiable_object.product_image_form_handler');
}
private function getProductShopImagesJsonResponse(int $productId): JsonResponse
{
/** @var ShopProductImagesCollection $shopImages */
$shopImages = $this->getQueryBus()->handle(new GetShopProductImages($productId));
return new JsonResponse($this->formatShopImages($shopImages));
}
/**
* @param int $productImageId
*
* @return JsonResponse
*/
private function getProductImageJsonResponse(int $productImageId): JsonResponse
{
$productImage = $this->getQueryBus()->handle(new GetProductImage(
$productImageId,
ShopConstraint::shop($this->getContextShopId())
));
return $this->json($this->formatImage($productImage));
}
/**
* @param ProductImage $image
*
* @return array<string, mixed>
*/
private function formatImage(ProductImage $image): array
{
return [
'image_id' => $image->getImageId(),
'is_cover' => $image->isCover(),
'position' => $image->getPosition(),
'image_url' => $image->getImageUrl(),
'thumbnail_url' => $image->getThumbnailUrl(),
'legends' => $image->getLocalizedLegends(),
'shop_ids' => $image->getShopIds(),
];
}
/**
* @param ShopProductImagesCollection $shopImagesCollection
*
* @return array<int, array{shopId: int, shopName: string, images: array<int, array{imageId: int, isCover: bool}>}>
*/
private function formatShopImages(ShopProductImagesCollection $shopImagesCollection): array
{
/** @var ShopRepository $shopRepository */
$shopRepository = $this->get(ShopRepository::class);
$formattedShopsImages = [];
foreach ($shopImagesCollection as $shopProductImage) {
$shopImages = [
'shopId' => $shopProductImage->getShopId(),
'shopName' => $shopRepository->getShopName(new ShopId($shopProductImage->getShopId())),
'images' => [],
];
/** @var ShopImageAssociation $shopImageAssociation */
foreach ($shopProductImage->getProductImages() as $shopImageAssociation) {
$shopImages['images'][] = [
'imageId' => $shopImageAssociation->getImageId(),
'isCover' => $shopImageAssociation->isCover(),
];
}
$formattedShopsImages[] = $shopImages;
}
return $formattedShopsImages;
}
/**
* Gets an error by exception class and its code.
*
* @param Exception $e
*
* @return array
*/
private function getErrorMessages(Exception $e): array
{
$messages = [
ProductConstraintException::class => [
ProductConstraintException::INVALID_ID => $this->trans(
'Invalid ID.',
'Admin.Notifications.Error'
),
],
ProductImageNotFoundException::class => $this->trans(
'The object cannot be loaded (or found).',
'Admin.Notifications.Error'
),
UploadedImageConstraintException::class => [
UploadedImageConstraintException::UNRECOGNIZED_FORMAT => $this->trans(
'Image format not recognized, allowed formats are: .gif, .jpg, .png',
'Admin.Notifications.Error'
),
],
MemoryLimitException::class => $this->trans(
'Due to memory limit restrictions, this image cannot be loaded. Please increase your memory_limit value via your server\'s configuration settings.',
'Admin.Notifications.Error'
),
CannotAddProductImageException::class => $this->trans(
'An error occurred while attempting to save.',
'Admin.Notifications.Error'
),
FileUploadException::class => [
UPLOAD_ERR_NO_FILE => $this->trans(
'No file was uploaded.',
'Admin.Notifications.Error'
),
],
CannotUnlinkImageException::class => $this->trans(
'Cannot delete file',
'Admin.Notifications.Error'
),
CannotRemoveCoverException::class => $this->trans(
'Cannot remove cover image.',
'Admin.Notifications.Error'
),
];
if ($e instanceof UploadedImageSizeException) {
$messages[UploadedImageSizeException::class] = $this->trans(
'Max file size allowed is "%s" bytes.',
'Admin.Notifications.Error',
[$e->getAllowedSizeBytes()]
);
}
return $messages;
}
}