diff --git a/README.md b/README.md index 04bd17f..1ed591f 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,6 @@ The overall aim of this module is twofold: * [Queued jobs](#queued-jobs) * [Case Studies](docs/en/case-studies.md) * [Fluent support](docs/en/fluent.md) -* [GridField Orderable support](docs/en/gridfield-orderable.md) * [License](license.md) * [Maintainers](#maintainers) * [Development and contribution](#development-and-contribution) @@ -41,6 +40,13 @@ The overall aim of this module is twofold: composer require silverstripe-terraformers/keys-for-cache ``` +## Requirements + +* PHP `^8.1` +* Silverstripe Framework `^5` + +Support for Silverstripe 4 is provided though our `^1` tagged releases. + ## Why cache keys are difficult The goal of any cache key is to have as low a cost as possible to calculate (as this must happen with every request), @@ -289,9 +295,6 @@ See: [Case studies](docs/en/case-studies.md) See: [Fluent support](docs/en/fluent.md) -## GridField Orderable support - -See: [GridField Orderable support](docs/en/gridfield-orderable.md) ## License diff --git a/composer.json b/composer.json index f89851a..7b6b871 100644 --- a/composer.json +++ b/composer.json @@ -19,13 +19,13 @@ } ], "require": { - "php": "^7.4 || ^8.0", - "silverstripe/framework": "^4.6" + "php": "^8.1", + "silverstripe/framework": "^5" }, "require-dev": { "phpunit/phpunit": "^9.5", - "tractorcow/silverstripe-fluent": ">=4.0.0", - "slevomat/coding-standard": "~6.0" + "tractorcow/silverstripe-fluent": "^7", + "slevomat/coding-standard": "~8.8.0" }, "autoload": { "psr-4": { diff --git a/docs/en/gridfield-orderable.md b/docs/en/gridfield-orderable.md deleted file mode 100644 index 07734e7..0000000 --- a/docs/en/gridfield-orderable.md +++ /dev/null @@ -1,43 +0,0 @@ -# GridField Orderable support - -* [Considerations & Warnings](#considerations--warnings) -* [Applying the Extension](#applying-the-extension) - -## Considerations & Warnings - -If you are using `symbiote/silverstripe-gridfieldextensions` version `3.5.0` or newer, then you have nothing to worry -about. Full support for all types of `DataObjects` is available. - -If you are using a `symbiote/silverstripe-gridfieldextensions` version lower than `3.5.0`, and you're using the -`GridFieldOrderableRows` component: - -* `GridFieldOrderableRows` will have out of the box support for KFC for `Versioned` DataObjects, as it already uses the - ORM and the `write()` method to save sort orders. -* `GridFieldOrderableRows` unfortunately does **not** use the `write()` method for non `Versioned` DataObjects, it - instead performs raw SQL queries, which completely bypasses the triggers we have attached to `write()`. - -There is an open ticket on the GridFieldExtensions module to try and get GridFieldOrderableRows to use the ORM for both -Versioned and non-Versioned DataObjects: -https://github.com/symbiote/silverstripe-gridfieldextensions/issues/335 - -In the meantime though, we have provided an Extension that adds support for clearing of CacheKeys on non `Versioned` -DataObjects when you are using the GridFieldOrderableRows component. - -* `GridFieldOrderableRowsExtension` - -This Extension is *not* automatically applied, because I think you should seriously consider Versioning your DataObject. -If you are adding this DataObject to (something like) an Element, which **is** Versioned, then (imo) it is best that all -of the related DataObjects (like its "Items") are also `Versioned`. This gives a consistent author experience - where -they can have draft/live versions of things. - -This Extension also doesn't have any test coverage (because of everything we mentioned above). It has only gone through -manual testing. Use at your own risk and be prepared to submit tickets if you find any issues or use cases that aren't -supported. - -## Applying the Extension - -```yaml -Symbiote\GridFieldExtensions\GridFieldOrderableRows: - extensions: - - Terraformers\KeysForCache\Extensions\GridFieldOrderableRowsExtension -``` diff --git a/phpcs.xml.dist b/phpcs.xml.dist index c8b7e75..06da3fd 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -5,6 +5,11 @@ src tests + + + + + @@ -75,6 +80,26 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 745ac44..2dbbe21 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,9 +1,12 @@ + - - tests/ - + + + tests + + - + src/ tests/ diff --git a/src/DataTransferObjects/CacheKeyDto.php b/src/DataTransferObjects/CacheKeyDto.php index e440eca..0423023 100644 --- a/src/DataTransferObjects/CacheKeyDto.php +++ b/src/DataTransferObjects/CacheKeyDto.php @@ -4,11 +4,8 @@ class CacheKeyDto { - private ?string $key; - - public function __construct(?string $key) + public function __construct(private ?string $key) { - $this->key = $key; } public function getKey(): ?string diff --git a/src/DataTransferObjects/EdgeUpdateDto.php b/src/DataTransferObjects/EdgeUpdateDto.php index dda4dd8..7ac328f 100644 --- a/src/DataTransferObjects/EdgeUpdateDto.php +++ b/src/DataTransferObjects/EdgeUpdateDto.php @@ -7,13 +7,9 @@ class EdgeUpdateDto { - private Edge $edge; - private DataObject $instance; - public function __construct(Edge $edge, DataObject $instance) + public function __construct(private readonly Edge $edge, private readonly DataObject $instance) { - $this->edge = $edge; - $this->instance = $instance; } public function getEdge(): Edge diff --git a/src/DataTransferObjects/ProcessedUpdateDto.php b/src/DataTransferObjects/ProcessedUpdateDto.php index e862ed5..34fd618 100644 --- a/src/DataTransferObjects/ProcessedUpdateDto.php +++ b/src/DataTransferObjects/ProcessedUpdateDto.php @@ -4,16 +4,10 @@ class ProcessedUpdateDto { - private string $className; - - private int $id; - private bool $published = false; - public function __construct(string $className, int $id) + public function __construct(private readonly string $className, private readonly int $id) { - $this->className = $className; - $this->id = $id; } public function getClassName(): string diff --git a/src/Extensions/GridFieldOrderableRowsExtension.php b/src/Extensions/GridFieldOrderableRowsExtension.php deleted file mode 100644 index ffb890e..0000000 --- a/src/Extensions/GridFieldOrderableRowsExtension.php +++ /dev/null @@ -1,147 +0,0 @@ - currentSortValue] - * @param array $sortedIDs [newSortValue => listItemID] - * @return void - */ - public function onAfterReorderItems(SS_List $list, array $values, array $sortedIDs): void - { - // We only support this action for DataList and ArrayList (as we know they can hold DataObjects) - if (!$list instanceof DataList && !$list instanceof ArrayList) { - return; - } - - $class = $list->dataClass(); - $isVersioned = false; - - // This is important for two reasons. The first is that we need to know whether we are sorting a Through - // class or the Relation class. The second is that we need to know if that DataObject is Versioned, if it is - // then the default GridFieldOrderableRows::reorderItems() will have triggered all the actions we need already - if ($list instanceof ManyManyThroughList) { - // We'll be updating the Through class, not the Relation class - $class = $this->getManyManyInspector($list)->getJoinClass(); - $isVersioned = $class::create()->hasExtension(Versioned::class); - } elseif (!$this->isManyMany($list)) { - $isVersioned = $class::create()->hasExtension(Versioned::class); - } - - // Check to see whether this List would already have been processed through the ORM, and therefor has already - // triggered the events that we need - if ($isVersioned) { - return; - } - - // We can't do anything with the Ordered DataObject if it doesn't have our CacheKeyExtension applied - if (!DataObject::has_extension($class, CacheKeyExtension::class)) { - return; - } - - // The problem is that $sortedIDs is a list of the _related_ item IDs, which causes trouble - // with ManyManyThrough, where we need the ID of the _join_ item in order to set the value. - $itemToSortReference = $list instanceof ManyManyThroughList - ? 'getJoin' - : 'Me'; - $currentSortList = $list->map('ID', $itemToSortReference)->toArray(); - - // Our List has already been processed and saved at this point, so we cannot access anything like the changed() - // methods for our DataObjects - // We do, however, have the original and new sort values, so we can run a comparison on those - foreach ($sortedIDs as $sortValue => $listItemID) { - // It should exist, but if it doesn't we'll just ignore it - if (!array_key_exists($listItemID, $values)) { - continue; - } - - // Check to see if the value is still the same as it was before. If it is, then we don't need to do anything - if ($values[$listItemID] === $sortValue) { - continue; - } - - /** @var DataObject|CacheKeyExtension $record */ - $record = $currentSortList[$listItemID]; - - // Sanity checks - if (!$record->isInDB()) { - continue; - } - - // We know that we need to publish these events, as this is a non-Versioned DataObject - $record->triggerCacheEvent(true); - } - } - - /** - * This is a copy/paste of the method used in GridFieldOrderableRow. We need it here as we're performing the same - * check/s - * - * @param SS_List $list - * @return DataQueryManipulator|ManyManyThroughQueryManipulator|SS_List - */ - private function getManyManyInspector(SS_List $list) - { - $inspector = $list; - - if (!$list instanceof ManyManyThroughList) { - return $inspector; - } - - foreach ($list->dataQuery()->getDataQueryManipulators() as $manipulator) { - if (!$manipulator instanceof ManyManyThroughQueryManipulator) { - continue; - } - - return $manipulator; - } - - return $inspector; - } - - private function isManyMany(SS_List $list): bool - { - return $list instanceof ManyManyList || $list instanceof ManyManyThroughList; - } -} diff --git a/src/RelationshipGraph/Edge.php b/src/RelationshipGraph/Edge.php index da59c56..6179774 100644 --- a/src/RelationshipGraph/Edge.php +++ b/src/RelationshipGraph/Edge.php @@ -4,17 +4,12 @@ class Edge { - private Node $from; - private Node $to; - private string $relation; - private string $relationType; - - public function __construct(Node $from, Node $to, string $relation, string $relationType) - { - $this->from = $from; - $this->to = $to; - $this->relation = $relation; - $this->relationType = $relationType; + public function __construct( + private readonly Node $from, + private readonly Node $to, + private readonly string $relation, + private readonly string $relationType + ) { } public function getFromClassName(): string diff --git a/src/RelationshipGraph/Node.php b/src/RelationshipGraph/Node.php index ec7eea6..40482de 100644 --- a/src/RelationshipGraph/Node.php +++ b/src/RelationshipGraph/Node.php @@ -4,11 +4,8 @@ class Node { - private string $className; - - public function __construct(string $className) + public function __construct(private readonly string $className) { - $this->className = $className; } public function getClassName(): string