Skip to content

Commit

Permalink
Merge pull request #2768 from dpfaffenbauer/issue/version-marshalling
Browse files Browse the repository at this point in the history
[ResourceBundle] Version Marshalling for FieldCollections
  • Loading branch information
dpfaffenbauer authored Dec 31, 2024
2 parents 01e599d + d974dd4 commit 006604f
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

/*
* CoreShop
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - CoreShop Commercial License (CCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) CoreShop GmbH (https://www.coreshop.org)
* @license https://www.coreshop.org/license GPLv3 and CCL
*
*/

namespace CoreShop\Bundle\ResourceBundle\DeepCopy;

use DeepCopy\Matcher\Matcher;
use Pimcore\Model\DataObject\Fieldcollection;

class PimcoreFieldCollectionDefinitionMatcher implements Matcher
{
public function __construct(private string $matchType)
{
}

public function matches(mixed $object, mixed $property): bool
{
if ($object instanceof Fieldcollection\Data\AbstractData) {
$collectionDef = Fieldcollection\Definition::getByKey($object->getType());

if ($collectionDef instanceof Fieldcollection\Definition) {
return $collectionDef->getFieldDefinition($property) instanceof $this->matchType;
}
}

return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

/*
* CoreShop
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - CoreShop Commercial License (CCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) CoreShop GmbH (https://www.coreshop.org)
* @license https://www.coreshop.org/license GPLv3 and CCL
*
*/

namespace CoreShop\Bundle\ResourceBundle\DeepCopy;

use DeepCopy\Filter\Filter;
use DeepCopy\Reflection\ReflectionHelper;
use Pimcore\Model\DataObject\Concrete;
use Pimcore\Model\DataObject\Fieldcollection;

class PimcoreFieldCollectionDefinitionReplaceFilter implements Filter
{
public function __construct(protected \Closure $callback)
{
}

public function apply($object, $property, $objectCopier)
{
if (!$object instanceof Fieldcollection\Data\AbstractData) {
return;
}

$fieldDefinition = $object->getDefinition()->getFieldDefinition($property);

if (!$fieldDefinition) {
return;
}

$reflectionProperty = ReflectionHelper::getProperty($object, $property);
$reflectionProperty->setAccessible(true);

$value = ($this->callback)($object, $fieldDefinition, $property, $reflectionProperty->getValue($object));

$reflectionProperty->setValue($object, $value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,20 @@

namespace CoreShop\Bundle\ResourceBundle\EventListener;

use CoreShop\Bundle\ResourceBundle\DeepCopy\PimcoreFieldCollectionDefinitionMatcher;
use CoreShop\Bundle\ResourceBundle\DeepCopy\PimcoreFieldCollectionDefinitionReplaceFilter;
use CoreShop\Bundle\ResourceBundle\Pimcore\CacheMarshallerInterface;
use CoreShop\Component\Resource\Model\ResourceInterface;
use DeepCopy\DeepCopy;
use DeepCopy\Filter\Doctrine\DoctrineCollectionFilter;
use DeepCopy\Matcher\PropertyTypeMatcher;
use DeepCopy\TypeMatcher\TypeMatcher;
use Pimcore\Event\SystemEvents;
use Pimcore\Model\DataObject\ClassDefinition\Data;
use Pimcore\Model\DataObject\Concrete;
use Pimcore\Model\DataObject\Fieldcollection\Data\AbstractData;
use Pimcore\Model\Element\DeepCopy\PimcoreClassDefinitionMatcher;
use Pimcore\Model\Element\DeepCopy\PimcoreClassDefinitionReplaceFilter;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\GenericEvent;

Expand Down Expand Up @@ -55,6 +62,41 @@ public function addDoctrineCollectionFilter(GenericEvent $event): void
$event->setArgument('copier', $copier);
}

if (($context['source'] ?? false) === 'Pimcore\Model\Version::marshalData') {
/**
* Pimcore handles CustomVersionMarshallInterface for Objects, but not for Fieldcollections
* this means that our custom types, get fully copied and serialized in to the version file
* meaning that for Cart Price Rules, you can end up serializing 100MB of data.... 🙈
*/
$copier->addFilter(
new PimcoreFieldCollectionDefinitionReplaceFilter(
function (AbstractData $object, Data $fieldDefinition, mixed $property, mixed $currentValue): mixed {
if ($fieldDefinition instanceof Data\CustomVersionMarshalInterface) {
return $fieldDefinition->marshalVersion($object->getObject(), $currentValue);
}

return $currentValue;
}
),
new PimcoreFieldCollectionDefinitionMatcher(Data\CustomVersionMarshalInterface::class)
);
}

if (($context['source'] ?? false) === 'Pimcore\Model\Version::unmarshalData') {
$copier->addFilter(
new PimcoreFieldCollectionDefinitionReplaceFilter(
function (AbstractData $object, Data $fieldDefinition, mixed $property, mixed $currentValue): mixed {
if ($fieldDefinition instanceof Data\CustomVersionMarshalInterface) {
return $fieldDefinition->unmarshalVersion($object->getObject(), $currentValue);
}

return $currentValue;
}
),
new PimcoreFieldCollectionDefinitionMatcher(Data\CustomVersionMarshalInterface::class)
);
}

if (($context['source'] ?? false) === 'Pimcore\Cache\Core\CoreCacheHandler::storeCacheData') {
/**
* This honestly absolutely sucks:
Expand Down

0 comments on commit 006604f

Please sign in to comment.