Skip to content

Commit

Permalink
Merge pull request #2389 from dpfaffenbauer/issues/cache
Browse files Browse the repository at this point in the history
[ResourceBundle] fix cache marshalling issues with CoreShop Doctrine …
  • Loading branch information
dpfaffenbauer authored Oct 11, 2023
2 parents 96a59f4 + ca669f4 commit ac08484
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@

namespace CoreShop\Bundle\ResourceBundle\EventListener;

use CoreShop\Bundle\ResourceBundle\Pimcore\CacheMarshallerInterface;
use DeepCopy\DeepCopy;
use DeepCopy\Filter\Doctrine\DoctrineCollectionFilter;
use DeepCopy\Matcher\PropertyTypeMatcher;
use DeepCopy\TypeMatcher\TypeMatcher;
use Pimcore\Event\SystemEvents;
use Pimcore\Model\DataObject\Concrete;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\GenericEvent;

Expand All @@ -38,17 +41,69 @@ public function addDoctrineCollectionFilter(GenericEvent $event): void
{
$context = $event->getArgument('context');

/**
* @var DeepCopy $copier
*/
$copier = $event->getArgument('copier');

//Only add if not already been added
if (!($context['defaultFilters'] ?? false)) {
/**
* @var DeepCopy $copier
*/
$copier = $event->getArgument('copier');
$copier->addFilter(
new DoctrineCollectionFilter(),
new PropertyTypeMatcher('Doctrine\Common\Collections\Collection'),
);
$event->setArgument('copier', $copier);
}

if (($context['source'] ?? false) === 'Pimcore\Cache\Core\CoreCacheHandler::storeCacheData') {
/**
* This honestly absolutely sucks:
*
* Pimcore's cache marshalling is quite inconsistent:
* - for marshalling they use DeepCopy
* - for unmarshalling they use default symfony behaviour
* WHY???
* Why not simply use one for all and make it easier to extend or overwrite
*
* The Idea behind this is: this marshall's (sort of) the information for caching
* (We don't want to serialize all doctrine entities into cache, too slow, too much unnecessary queries)
*
* The CoreShop\Bundle\ResourceBundle\Pimcore\CacheResourceMarshaller then
* is responsible for unmarshalling the data again
*
* We have to do it in this order since Pimcore first does the DeepCopy and then
* default Symfony Marshalling, meaning for us, we cannot simply do it in one place either
*/
/** @psalm-suppress MissingClosureParamType */
$copier->addTypeFilter(
new \DeepCopy\TypeFilter\ReplaceFilter(
function ($currentValue) {
if (!$currentValue instanceof Concrete) {
return $currentValue;
}

$class = $currentValue->getClass();

if (!$class) {
return $currentValue;
}

foreach ($class->getFieldDefinitions() as $fd) {
if (!$fd instanceof CacheMarshallerInterface) {
continue;
}

$currentValue->setObjectVar(
$fd->getName(),
$fd->marshalForCache($currentValue, $currentValue->getObjectVar($fd->getName()))
);
}

return $currentValue;
}
),
new TypeMatcher(Concrete::class)
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ services:
- '@CoreShop\Component\Resource\Metadata\RegistryInterface'
- '@CoreShop\Component\Pimcore\DataObject\ObjectServiceInterface'

CoreShop\Bundle\ResourceBundle\Pimcore\CacheResourceMarshaller: ~
CoreShop\Bundle\ResourceBundle\Pimcore\CacheResourceMarshaller:
decorates: cache.default_marshaller

CoreShop\Bundle\ResourceBundle\Slug\ResourceConfigurationSlugGenerator:
decorates: 'CoreShop\Component\Pimcore\Slug\DataObjectSlugGeneratorInterface'
Expand Down

0 comments on commit ac08484

Please sign in to comment.