Assign images to products programmatically
-
15-04-2021 - |
Вопрос
I want to assign images to products in my store. The images name the same SKU product name. I put my PHP file in root/pub and tried this code:
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
/*
* Assumes doc root is set to ROOT/pub
*/
require_once dirname(__DIR__) . '/app/bootstrap.php';
$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);
class AssignImages extends \Magento\Framework\App\Http implements \Magento\Framework\AppInterface
{
public function launch()
{
$state = $this->_objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('adminhtml');
$galleryReadHandler = $this->_objectManager->create('Magento\Catalog\Model\Product\Gallery\ReadHandler');
$imageProcessor = $this->_objectManager->create('Magento\Catalog\Model\Product\Gallery\Processor');
$productGallery = $this->_objectManager->create('Magento\Catalog\Model\ResourceModel\Product\Gallery');
/**
* Assumed images are named [sku].[ext] and reside in ROOT/pub/media/[image_dir]
*/
foreach (glob(__DIR__ . "/media/img/*.{jpg,png,gif}", GLOB_BRACE) as $image) {
$imageFileName = trim(pathinfo($image)['filename']);
$sku = $imageFileName;
try {
$product = $this->_objectManager->create('Magento\Catalog\Model\Product')->loadByAttribute('sku', $sku);
if ($product) {
$galleryReadHandler->execute($product);
// Unset existing images
$images = $product->getMediaGalleryImages();
foreach($images as $child) {
$productGallery->deleteGallery($child->getValueId());
$imageProcessor->removeImage($product, $child->getFile());
}
/**
* Add image. Image directory must be in ROOT/pub/media for addImageToMediaGallery() method to work
*/
$product->addImageToMediaGallery('img' . DIRECTORY_SEPARATOR . pathinfo($image)['basename'], array('image', 'small_image', 'thumbnail'), false, false);
$product->save();
echo "Added media image for {$sku}" . "\n";
}
} catch (\Exception $e) {
echo $e->getMessage();
}
}
return $this->_response;
}
public function catchException(\Magento\Framework\App\Bootstrap $bootstrap, \Exception $exception)
{
echo $exception->getMessage();
return false;
}
}
/** @var \Magento\Framework\App\Http $app */
$app = $bootstrap->createApplication('AssignImages');
$bootstrap->run($app);
?>
But display this error:
Fatal error: Declaration of AssignImages::catchException(Magento\Framework\App\Bootstrap $bootstrap, Exception $exception) must be compatible with Magento\Framework\App\Http::catchException(Magento\Framework\App\Bootstrap $bootstrap, Exception $exception): bool in /home/tabasheermedia/public_html/no-limits/pub/importimage.php on line 12
My Magento version 2.3.3
Решение
1)Add a file within the ROOT/pub directory containing the code below and run the code either within the browser or via CLI.
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once dirname(__DIR__) . '/app/bootstrap.php';
$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);
class AssignImages extends \Magento\Framework\App\Http implements \Magento\Framework\AppInterface
{
public function launch()
{
$state = $this->_objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('adminhtml');
$galleryReadHandler = $this->_objectManager->create('Magento\Catalog\Model\Product\Gallery\ReadHandler');
$imageProcessor = $this->_objectManager->create('Magento\Catalog\Model\Product\Gallery\Processor');
$productGallery = $this->_objectManager->create('Magento\Catalog\Model\ResourceModel\Product\Gallery');
foreach (glob(__DIR__ . "/media/[image_dir]/*.{jpg,png,gif}", GLOB_BRACE) as $image) {
$imageFileName = trim(pathinfo($image)['filename']);
$sku = $imageFileName;
try {
$product = $this->_objectManager->create('Magento\Catalog\Model\Product')->loadByAttribute('sku', $sku);
if ($product) {
$galleryReadHandler->execute($product);
// Unset existing images
$images = $product->getMediaGalleryImages();
foreach($images as $child) {
$productGallery->deleteGallery($child->getValueId());
$imageProcessor->removeImage($product, $child->getFile());
}
$product->addImageToMediaGallery('[image_dir]' . DIRECTORY_SEPARATOR . pathinfo($image)['basename'], array('image', 'small_image', 'thumbnail'), false, false);
$product->save();
echo "Added media image for {$sku}" . "\n";
}
} catch (\Exception $e) {
echo $e->getMessage();
}
}
return $this->_response;
}
public function catchException(\Magento\Framework\App\Bootstrap $bootstrap, \Exception $exception)
{
echo $exception->getMessage();
return false;
}
}
/** @var \Magento\Framework\App\Http $app */
$app = $bootstrap->createApplication('AssignImages');
$bootstrap->run($app);
2)Add Or Remove Media Images Programmatically By Using Object Manager
// Instance of object manager
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
//Remove Images From Product
$productId = 1 ; // Id of product
$product = $objectManager->create('Magento\Catalog\Model\Product')->load($productId);
$productRepository = $objectManager->create('Magento\Catalog\Api\ProductRepositoryInterface');
$existingMediaGalleryEntries = $product->getMediaGalleryEntries();
foreach ($existingMediaGalleryEntries as $key => $entry) {
unset($existingMediaGalleryEntries[$key]);
}
$product->setMediaGalleryEntries($existingMediaGalleryEntries);
$productRepository->save($product);
/*Add Images To The Product*/
$imagePath = "sample.png"; // path of the image
$product->addImageToMediaGallery($imagePath, array('image', 'small_image', 'thumbnail'), false, false);
$product->save();
Другие советы
The answer is in the error - your class is extending \Magento\Framework\App\Http
so your catchException method should also declare the return type as bool
public function catchException(Bootstrap $bootstrap, \Exception $exception): bool
{
return false;
}