Skip to content

Commit

Permalink
AKM-20: Compatibility with the non-empty filename fix for OroCommerce …
Browse files Browse the repository at this point in the history
- Disable DAM
- Reuse UUID from the DB
- Fix validators performance
- Fix files import
  • Loading branch information
dxops committed Feb 16, 2021
1 parent f9d0551 commit ce1ca0f
Show file tree
Hide file tree
Showing 11 changed files with 363 additions and 10 deletions.
22 changes: 22 additions & 0 deletions EventListener/LoadClassMetadataListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Oro\Bundle\AkeneoBundle\EventListener;

use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Oro\Bundle\AttachmentBundle\Entity\File;

class LoadClassMetadataListener
{
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
$classMetadata = $eventArgs->getClassMetadata();

if (is_a($classMetadata->getName(), File::class, true)) {
$classMetadata->table['indexes']['oro_akeneo_file_parent_index'] = [
'columns' => ['parent_entity_class', 'parent_entity_id'],
];

$classMetadata->fieldMappings[$classMetadata->getFieldForColumn('parent_entity_class')]['length'] = 255;
}
}
}
41 changes: 36 additions & 5 deletions ImportExport/Processor/ProductImageImportProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,25 @@

namespace Oro\Bundle\AkeneoBundle\ImportExport\Processor;

use Oro\Bundle\BatchBundle\Item\Support\ClosableInterface;
use Oro\Bundle\IntegrationBundle\ImportExport\Processor\StepExecutionAwareImportProcessor;
use Oro\Bundle\ProductBundle\Entity\Product;
use Oro\Bundle\ProductBundle\Entity\ProductImage;
use Oro\Bundle\ProductBundle\Entity\ProductImageType;

class ProductImageImportProcessor extends StepExecutionAwareImportProcessor
class ProductImageImportProcessor extends StepExecutionAwareImportProcessor implements ClosableInterface
{
public function close()
{
if ($this->strategy instanceof ClosableInterface) {
$this->strategy->close();
}

if ($this->dataConverter instanceof ClosableInterface) {
$this->dataConverter->close();
}
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -70,23 +82,31 @@ private function mergeImages(Product $product, array $images): Product
continue;
}

if (!is_a($image->getImage()->getParentEntityClass(), ProductImage::class, true)) {
$image->setImage(null);

$product->removeImage($image);

continue;
}

$filename = $image->getImage()->getOriginalFilename();
if (!in_array($filename, array_keys($images))) {
$product->removeImage($image);

continue;
}

if ($hasMain && $image->hasType(ProductImageType::TYPE_MAIN)) {
if ($hasMain && $this->hasType($image, ProductImageType::TYPE_MAIN)) {
$image->removeType(ProductImageType::TYPE_MAIN);
}

if ($hasListing && $image->hasType(ProductImageType::TYPE_LISTING)) {
if ($hasListing && $this->hasType($image, ProductImageType::TYPE_LISTING)) {
$image->removeType(ProductImageType::TYPE_LISTING);
}

$hasMain = $hasMain || $image->hasType(ProductImageType::TYPE_MAIN);
$hasListing = $hasListing || $image->hasType(ProductImageType::TYPE_LISTING);
$hasMain = $hasMain || $this->hasType($image, ProductImageType::TYPE_MAIN);
$hasListing = $hasListing || $this->hasType($image, ProductImageType::TYPE_LISTING);

unset($images[$filename]);
}
Expand All @@ -113,4 +133,15 @@ private function mergeImages(Product $product, array $images): Product

return $product;
}

private function hasType(ProductImage $image, string $type): bool
{
foreach ($image->getTypes() as $imageType) {
if ($imageType->getType() === $type) {
return true;
}
}

return false;
}
}
9 changes: 7 additions & 2 deletions ImportExport/Strategy/BrandImportStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function beforeProcessEntity($entity)
{
$this->setOwner($entity);

return $entity;
return parent::beforeProcessEntity($entity);
}

protected function afterProcessEntity($entity)
Expand All @@ -47,7 +47,12 @@ protected function afterProcessEntity($entity)
$this->addSlug($entity, $entity->getDefaultName());
}

return $entity;
$result = parent::afterProcessEntity($entity);
if (!$result && $entity) {
$this->processValidationErrors($entity, []);
}

return $result;
}

private function addSlug(Brand $brand, LocalizedFallbackValue $localizedName): void
Expand Down
61 changes: 59 additions & 2 deletions ImportExport/Strategy/ProductImageImportStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,28 @@

namespace Oro\Bundle\AkeneoBundle\ImportExport\Strategy;

use Oro\Bundle\BatchBundle\Item\Support\ClosableInterface;
use Oro\Bundle\ImportExportBundle\Strategy\Import\ConfigurableAddOrReplaceStrategy;
use Oro\Bundle\ProductBundle\Entity\Product;
use Oro\Bundle\ProductBundle\Entity\ProductImage;

/**
* Strategy to import product images.
*/
class ProductImageImportStrategy extends ConfigurableAddOrReplaceStrategy
class ProductImageImportStrategy extends ConfigurableAddOrReplaceStrategy implements ClosableInterface
{
use ImportStrategyAwareHelperTrait;

/**
* @var Product[]
*/
private $existingProducts = [];

public function close()
{
$this->existingProducts = [];
}

/**
* @param ProductImage $entity
*
Expand Down Expand Up @@ -39,10 +51,14 @@ protected function beforeProcessEntity($entity)
continue;
}

if (!is_a($image->getImage()->getParentEntityClass(), ProductImage::class, true)) {
continue;
}

if ($image->getImage()->getOriginalFilename() === $entity->getImage()->getOriginalFilename()) {
$itemData['image']['uuid'] = $image->getImage()->getUuid();

$entity = $image;
$this->fieldHelper->setObjectValue($entity, 'id', $image->getId());
}
}
$this->context->setValue('itemData', $itemData);
Expand Down Expand Up @@ -76,4 +92,45 @@ protected function validateBeforeProcess($entity)

return $entity;
}

protected function isFieldExcluded($entityName, $fieldName, $itemData = null)
{
$excludeImageFields = ['updatedAt', 'types'];

if (is_a($entityName, ProductImage::class, true) && in_array($fieldName, $excludeImageFields)) {
return true;
}

return parent::isFieldExcluded($entityName, $fieldName, $itemData);
}

protected function findExistingEntity($entity, array $searchContext = [])
{
if ($entity instanceof Product && array_key_exists($entity->getSku(), $this->existingProducts)) {
return $this->existingProducts[$entity->getSku()];
}

$entity = parent::findExistingEntity($entity, $searchContext);

if ($entity instanceof Product) {
$this->existingProducts[$entity->getSku()] = $entity;
}

return $entity;
}

protected function findExistingEntityByIdentityFields($entity, array $searchContext = [])
{
if ($entity instanceof Product && array_key_exists($entity->getSku(), $this->existingProducts)) {
return $this->existingProducts[$entity->getSku()];
}

$entity = parent::findExistingEntityByIdentityFields($entity, $searchContext);

if ($entity instanceof Product) {
$this->existingProducts[$entity->getSku()] = $entity;
}

return $entity;
}
}
1 change: 1 addition & 0 deletions ImportExport/Writer/AttributeWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ private function saveAttachmentConfig(string $className, string $fieldName, stri
$attachmentConfig = $attachmentProvider->getConfig($className, $fieldName);
$attachmentConfig->set('file_applications', ['default', 'commerce']);
$attachmentConfig->set('acl_protected', true);
$attachmentConfig->set('use_dam', false);
$attachmentConfig->set('maxsize', self::MAX_SIZE);
$attachmentConfig->set('width', self::MAX_WIDTH);
$attachmentConfig->set('height', self::MAX_HEIGHT);
Expand Down
27 changes: 27 additions & 0 deletions Migrations/Data/ORM/DisableDAM.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Oro\Bundle\DotmailerBundle\Migrations\Data\ORM;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;
use Oro\Bundle\EntityConfigBundle\Config\ConfigManager;
use Oro\Bundle\ProductBundle\Entity\ProductImage;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;

class DisableDAM extends AbstractFixture implements ContainerAwareInterface
{
use ContainerAwareTrait;

public function load(ObjectManager $manager)
{
/** @var ConfigManager $configManager */
$configManager = $this->container->get('oro_entity_config.config_manager');
$attachmentProvider = $configManager->getProvider('attachment');
$attachmentConfig = $attachmentProvider->getConfig(ProductImage::class, 'image');
$attachmentConfig->set('use_dam', false);

$configManager->persist($attachmentConfig);
$configManager->flush();
}
}
2 changes: 1 addition & 1 deletion Migrations/Schema/OroAkeneoBundleInstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class OroAkeneoBundleInstaller implements Installation, ExtendExtensionAwareInte
*/
public function getMigrationVersion()
{
return 'v1_13';
return 'v1_14';
}

/**
Expand Down
71 changes: 71 additions & 0 deletions Migrations/Schema/v1_14/OroAkeneoMigration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace Oro\Bundle\AkeneoBundle\Migrations\Schema\v1_14;

use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Schema\Schema;
use Oro\Bundle\MigrationBundle\Migration\Extension\DatabasePlatformAwareInterface;
use Oro\Bundle\MigrationBundle\Migration\Extension\DatabasePlatformAwareTrait;
use Oro\Bundle\MigrationBundle\Migration\Migration;
use Oro\Bundle\MigrationBundle\Migration\QueryBag;

class OroAkeneoMigration implements Migration, DatabasePlatformAwareInterface
{
use DatabasePlatformAwareTrait;

public function up(Schema $schema, QueryBag $queries)
{
$queries->addPostQuery(
"UPDATE oro_attachment_file
SET owner_user_id = (SELECT default_user_owner_id FROM oro_integration_channel WHERE type = 'oro_akeneo' LIMIT 1)
WHERE owner_user_id IS NULL
AND parent_entity_class = 'Oro\Bundle\ProductBundle\Entity\Product'
AND parent_entity_field_name LIKE 'Akeneo%';"
);

if ($this->platform instanceof MySqlPlatform) {
$queries->addPostQuery(
"UPDATE oro_attachment_file
SET uuid = UUID();
WHERE parent_entity_class = 'Oro\Bundle\ProductBundle\Entity\Product'
AND parent_entity_field_name LIKE 'Akeneo%';"
);
} elseif ($this->platform instanceof PostgreSqlPlatform) {
$queries->addPostQuery(
"UPDATE oro_attachment_file
SET uuid = uuid_generate_v4()
WHERE parent_entity_class = 'Oro\Bundle\ProductBundle\Entity\Product'
AND parent_entity_field_name LIKE 'Akeneo%';"
);
}

$queries->addPostQuery(
"UPDATE oro_attachment_file
SET owner_user_id = (SELECT default_user_owner_id FROM oro_integration_channel WHERE type = 'oro_akeneo' LIMIT 1)
WHERE owner_user_id IS null
AND parent_entity_class = 'Oro\Bundle\ProductBundle\Entity\ProductImage'
AND parent_entity_field_name = 'image';"
);

if ($this->platform instanceof MySqlPlatform) {
$queries->addPostQuery(
"UPDATE oro_attachment_file
SET uuid = UUID();
WHERE parent_entity_class = 'Oro\Bundle\ProductBundle\Entity\ProductImage'
AND parent_entity_field_name = 'image';"
);
} elseif ($this->platform instanceof PostgreSqlPlatform) {
$queries->addPostQuery(
"UPDATE oro_attachment_file
SET uuid = uuid_generate_v4()
WHERE parent_entity_class = 'Oro\Bundle\ProductBundle\Entity\ProductImage'
AND parent_entity_field_name = 'image';"
);
}

$table = $schema->getTable('oro_attachment_file');
$table->getColumn('parent_entity_class')->setLength(255);
$table->addIndex(['parent_entity_class', 'parent_entity_id'], 'oro_akeneo_file_parent_index');
}
}
23 changes: 23 additions & 0 deletions Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,24 @@ services:
tags:
- { name: validator.constraint_validator, alias: oro_akeneo.attribute_mapping_validator }

oro_akeneo.validator.unique_variant_links:
class: 'Oro\Bundle\AkeneoBundle\Validator\UniqueProductVariantLinksValidator'
decorates: oro_product.validator.unique_variant_links
arguments:
- '@oro_entity.doctrine_helper'
- '@oro_akeneo.validator.unique_variant_links.inner'
tags:
- { name: validator.constraint_validator, alias: oro_product_unique_variant_links }

oro_akeneo.validator.unique_variant_links_simple_product:
class: 'Oro\Bundle\AkeneoBundle\Validator\UniqueVariantLinksSimpleProductValidator'
decorates: oro_product.validator.unique_variant_links_simple_product
arguments:
- '@oro_entity.doctrine_helper'
- '@oro_akeneo.validator.unique_variant_links_simple_product.inner'
tags:
- { name: validator.constraint_validator, alias: oro_product_unique_variant_links_simple_product }

oro_akeneo.event_subscriber.doctrine:
class: 'Oro\Bundle\AkeneoBundle\EventSubscriber\DoctrineSubscriber'
calls:
Expand Down Expand Up @@ -131,6 +149,11 @@ services:
arguments:
- '@oro_akeneo.event_listener.import_export_tags_subscriber.decorator.inner'

oro_akeneo.event_listener.load_class_metadata:
class: Oro\Bundle\AkeneoBundle\EventListener\LoadClassMetadataListener
tags:
- { name: doctrine.event_listener, event: loadClassMetadata }

oro_akeneo.event_listener.product_collection_variant_reindex_message_send_listener.decorator:
class: Oro\Bundle\AkeneoBundle\EventListener\ProductCollectionVariantReindexMessageSendListenerDecorator
decorates: oro_product.entity.event_listener.product_collection_variant_reindex_message_send_listener
Expand Down
Loading

0 comments on commit ce1ca0f

Please sign in to comment.