Skip to content

Commit

Permalink
Merge pull request #2398 from dpfaffenbauer/issues/cache-improvements
Browse files Browse the repository at this point in the history
[Cache] cache improvements - decorate Pimcore CoreCacheHandler
  • Loading branch information
dpfaffenbauer authored Oct 20, 2023
2 parents eddd5b0 + f8cf625 commit 0a46fbf
Show file tree
Hide file tree
Showing 16 changed files with 403 additions and 133 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,5 @@ public/bundles
public/var
drivers
vendor/
cache/
docs/generated-docs
node_modules
19 changes: 19 additions & 0 deletions features/domain/cache/check_cache_size.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@domain @cache
Feature: Adding a new Product and adding it to the cache

Background:
Given the site operates on a store in "Austria"
And the site has a tax rate "AT" with "20%" rate
And the site has a tax rule group "AT"
And the tax rule group has a tax rule for country "Austria" with tax rate "AT"
And the site has a product "T-Shirt" priced at 2000
And the product has the tax rule group "AT"

Scenario: Test caching the product
Given the product "T-Shirt" is cached with key "tshirt"
And I restore the object from the cache
Then the cache item should be a DataObject
And the cache item should have an object-var "taxRule" with value of tax rule group
And the cache item serialized should have a property "taxRule" with value of tax rule group
Given I restore the object with Pimcore Cache Helper
Then the cache object should have an object-var "taxRule" of type ResourceInterface
110 changes: 110 additions & 0 deletions src/CoreShop/Behat/Context/Domain/CacheContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?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\Behat\Context\Domain;

use Behat\Behat\Context\Context;
use CoreShop\Behat\Service\SharedStorageInterface;
use CoreShop\Component\Resource\Model\ResourceInterface;
use Pimcore\Model\DataObject\Concrete;
use Symfony\Component\Cache\CacheItem;
use Webmozart\Assert\Assert;

final class CacheContext implements Context
{
public function __construct(
private SharedStorageInterface $sharedStorage,
) {
}

/**
* @Then /^the (cache item) should be a DataObject$/
*/
public function theCacheItemShouldBeADataObject(CacheItem $cacheItem): void
{
Assert::true($cacheItem->get() instanceof Concrete);
}

/**
* @Then /^the (cache item) should have an object-var "([^"]+)" with value "([^"]+)"/
* @Then /^the (cache item) should have an object-var "([^"]+)" with value of (tax rule group)/
*/
public function theCacheItemShouldHaveAObjectVarWithValue(CacheItem $cacheItem, string $property, mixed $value): void
{
Assert::true($cacheItem->get() instanceof Concrete);
/**
* @var Concrete $item
*/
$item = $cacheItem->get();
$objectValue = $item->getObjectVar($property);

if ($value instanceof ResourceInterface) {
$value = $value->getId();
}

Assert::same((string)$objectValue, (string)$value);
}

/**
* @Then /^the (cache object) should have an object-var "([^"]+)" of type ResourceInterface/
*/
public function theCacheItemShouldHaveAObjectVarOfTypeResource(Concrete $cacheObject, string $property): void
{
$objectValue = $cacheObject->getObjectVar($property);

Assert::isInstanceOf($objectValue, ResourceInterface::class);
}


/**
* @Then /^the (cache item) serialized should have a property "([^"]+)" with value "([^"]+)"/
* @Then /^the (cache item) serialized should have a property "([^"]+)" with value of (tax rule group)/
*/
public function theCacheItemSerializedShouldLookLikeTheKnownOne(CacheItem $cacheItem, string $property, mixed $value): void
{
$itemData = $cacheItem->get();
if (!is_scalar($itemData)) {
$itemData = serialize($itemData);
}

$serializedNull = unserialize($itemData, ['allowed_classes' => false]);

$convertToStdClass = static function(\__PHP_Incomplete_Class $object)
{
$dump = serialize($object);
$dump = preg_replace('/^O:\d+:"[^"]++"/', 'O:8:"stdClass"', $dump);
$dump = preg_replace_callback(
'/:\d+:"\0.*?\0([^"]+)"/',
static fn($matches) => ":".strlen($matches[1]).":\"".$matches[1]."\"",
$dump
);

return unserialize($dump);
};

$stdClass = $convertToStdClass($serializedNull);

$cacheValue = $stdClass->{$property};

if ($value instanceof ResourceInterface) {
$value = $value->getId();
}

Assert::same((string)$cacheValue, (string)$value);
}
}
69 changes: 69 additions & 0 deletions src/CoreShop/Behat/Context/Setup/CacheContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?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\Behat\Context\Setup;

use Behat\Behat\Context\Context;
use CoreShop\Behat\Service\SharedStorageInterface;
use Pimcore\Cache;
use Pimcore\Model\DataObject\Concrete;
use Webmozart\Assert\Assert;

final class CacheContext implements Context
{
public function __construct(
private SharedStorageInterface $sharedStorage,
) {
}

/**
* @Given /^the (product "[^"]+") is cached with key "([^"]+)"$/
*/
public function iCacheObjectWithKey(mixed $object, string $key): void
{
if ($object instanceof Concrete) {
Cache::getHandler()->removeClearedTags(['object_'.$object->getId()]);
Cache::getHandler()->removeClearedTags(['class_'.$object->getClassId()]);
}

Assert::true(Cache::getHandler()->save($key, $object, ['behat'], null, 0, true));

$this->sharedStorage->set('cache_key', $key);
}

/**
* @Given /^I restore the object from the cache$/
*/
public function iRestoreTheObjectFromTheCache(): void
{
$cacheItem = Cache::getHandler()->getItem($this->sharedStorage->get('cache_key'));

Assert::true($cacheItem->isHit());

$this->sharedStorage->set('cache_item', $cacheItem);
}

/**
* @Given /^I restore the object with Pimcore Cache Helper/
*/
public function iRestoreTheObjectWithPimcoreCacheHelper(): void
{
$obj = Cache::getHandler()->load($this->sharedStorage->get('cache_key'));
$this->sharedStorage->set('cache_object', $obj);
}
}
55 changes: 55 additions & 0 deletions src/CoreShop/Behat/Context/Transform/CacheContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?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\Behat\Context\Transform;

use Behat\Behat\Context\Context;
use CoreShop\Behat\Service\SharedStorageInterface;
use Pimcore\Cache;

final class CacheContext implements Context
{
public function __construct(
private SharedStorageInterface $sharedStorage,
) {
}

/**
* @Transform /^cache item "([^"]+)"$/
*/
public function cacheItemByKey($key): mixed
{
return Cache::getHandler()->getItem($key);
}

/**
* @Transform /^cache item$/
*/
public function cacheItem(): mixed
{
return $this->sharedStorage->get('cache_item');
}

/**
* @Transform /^cache object$/
*/
public function cacheObject(): mixed
{
return $this->sharedStorage->get('cache_object');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,10 @@ services:
- '@coreshop.behat.shared_storage'
tags:
- { name: fob.context_service }

coreshop.behat.context.domain.cache:
class: CoreShop\Behat\Context\Domain\CacheContext
arguments:
- '@coreshop.behat.shared_storage'
tags:
- { name: fob.context_service }
Original file line number Diff line number Diff line change
Expand Up @@ -382,3 +382,10 @@ services:
- '%kernel.project_dir%/etc/build'
tags:
- { name: fob.context_service }

coreshop.behat.context.setup.cache:
class: CoreShop\Behat\Context\Setup\CacheContext
arguments:
- '@coreshop.behat.shared_storage'
tags:
- { name: fob.context_service }
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,10 @@ services:
- '@coreshop.repository.attribute_value'
tags:
- { name: fob.context_service }

coreshop.behat.context.transform.cache:
class: CoreShop\Behat\Context\Transform\CacheContext
arguments:
- '@coreshop.behat.shared_storage'
tags:
- { name: fob.context_service }
1 change: 1 addition & 0 deletions src/CoreShop/Behat/Resources/config/suites/domain.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ imports:
- domain/recycle_bin.yml
- domain/optimistic_entity_lock.yml
- domain/payment_provider.yml
- domain/cache.yml
51 changes: 51 additions & 0 deletions src/CoreShop/Behat/Resources/config/suites/domain/cache.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
default:
suites:
domain_cache:
contexts:
- coreshop.behat.context.hook.pimcore_setup
- coreshop.behat.context.hook.coreshop_setup

- coreshop.behat.context.hook.doctrine_orm
- coreshop.behat.context.hook.pimcore_dao

- coreshop.behat.context.transform.shared_storage
- coreshop.behat.context.transform.product
- coreshop.behat.context.transform.product_price_rule
- coreshop.behat.context.transform.product_specific_price_rule
- coreshop.behat.context.transform.category
- coreshop.behat.context.transform.country
- coreshop.behat.context.transform.currency
- coreshop.behat.context.transform.customer
- coreshop.behat.context.transform.customer_group
- coreshop.behat.context.transform.zone
- coreshop.behat.context.transform.store
- coreshop.behat.context.transform.tax_rate
- coreshop.behat.context.transform.tax_rule_group
- coreshop.behat.context.transform.product_unit
- coreshop.behat.context.transform.cart
- coreshop.behat.context.transform.product_quantity_price_rule
- coreshop.behat.context.transform.variant
- coreshop.behat.context.transform.cache

- coreshop.behat.context.setup.product
- coreshop.behat.context.setup.product_price_rule
- coreshop.behat.context.setup.product_specific_price_rule
- coreshop.behat.context.setup.store
- coreshop.behat.context.setup.category
- coreshop.behat.context.setup.country
- coreshop.behat.context.setup.currency
- coreshop.behat.context.setup.customer
- coreshop.behat.context.setup.customer_group
- coreshop.behat.context.setup.zone
- coreshop.behat.context.setup.tax_rate
- coreshop.behat.context.setup.tax_rule_group
- coreshop.behat.context.setup.product_unit
- coreshop.behat.context.setup.pimcore_class
- coreshop.behat.context.setup.cart
- coreshop.behat.context.setup.product_quantity_price_rule
- coreshop.behat.context.setup.variant
- coreshop.behat.context.setup.cache

- coreshop.behat.context.domain.cache
filters:
tags: "@domain&&@cache"
Loading

0 comments on commit 0a46fbf

Please sign in to comment.