From 3f30d71e9d87f1198a3db3fec4184f1d3fc3af3b Mon Sep 17 00:00:00 2001 From: John Koster Date: Sat, 2 Mar 2024 17:49:03 -0600 Subject: [PATCH 1/5] Cache collection instance on Entry --- src/Entries/Entry.php | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/Entries/Entry.php b/src/Entries/Entry.php index 819ff7f3e3c..292940ba53a 100644 --- a/src/Entries/Entry.php +++ b/src/Entries/Entry.php @@ -78,6 +78,7 @@ class Entry implements Arrayable, ArrayAccess, Augmentable, ContainsQueryableVal protected $withEvents = true; protected $template; protected $layout; + protected $cachedCollectionInstance; public function __construct() { @@ -115,17 +116,20 @@ public function authors() public function collection($collection = null) { - return $this - ->fluentlyGetOrSet('collection') - ->setter(function ($collection) { - return $collection instanceof \Statamic\Contracts\Entries\Collection ? $collection->handle() : $collection; - }) - ->getter(function ($collection) { - return $collection ? Blink::once("collection-{$collection}", function () use ($collection) { - return Collection::findByHandle($collection); - }) : null; - }) - ->args(func_get_args()); + if (func_num_args() === 0) { + if ($this->cachedCollectionInstance) { + return $this->cachedCollectionInstance; + } + + return $this->cachedCollectionInstance = $this->collection ? Blink::once("collection-{$this->collection}", function () { + return Collection::findByHandle($this->collection); + }) : null; + } + + $this->cachedCollectionInstance = null; + $this->collection = $collection instanceof \Statamic\Contracts\Entries\Collection ? $collection->handle() : $collection; + + return $this; } public function blueprint($blueprint = null) From 7a0ed135c675b2169cdfb0b425ff14bb8bf3fd30 Mon Sep 17 00:00:00 2001 From: John Koster Date: Sat, 2 Mar 2024 18:24:43 -0600 Subject: [PATCH 2/5] Refactors; cache computed callbacks While the Blink call for collection is unfortunate, its still an improvement over the repeated getter/setter calls in this method due to how many times it is called. Cache invalidation complexity here is not worth it at this time --- src/Entries/Entry.php | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/Entries/Entry.php b/src/Entries/Entry.php index 292940ba53a..51409d6dac1 100644 --- a/src/Entries/Entry.php +++ b/src/Entries/Entry.php @@ -78,7 +78,7 @@ class Entry implements Arrayable, ArrayAccess, Augmentable, ContainsQueryableVal protected $withEvents = true; protected $template; protected $layout; - protected $cachedCollectionInstance; + protected $computedCallbackCache; public function __construct() { @@ -117,16 +117,12 @@ public function authors() public function collection($collection = null) { if (func_num_args() === 0) { - if ($this->cachedCollectionInstance) { - return $this->cachedCollectionInstance; - } - - return $this->cachedCollectionInstance = $this->collection ? Blink::once("collection-{$this->collection}", function () { + return $this->collection ? Blink::once("collection-{$this->collection}", function () { return Collection::findByHandle($this->collection); }) : null; } - $this->cachedCollectionInstance = null; + $this->computedCallbackCache = null; $this->collection = $collection instanceof \Statamic\Contracts\Entries\Collection ? $collection->handle() : $collection; return $this; @@ -1018,6 +1014,22 @@ public function getCpSearchResultBadge(): string protected function getComputedCallbacks() { - return Facades\Collection::getComputedCallbacks($this->collection); + if ($this->computedCallbackCache) { + return $this->computedCallbackCache; + } + + return $this->computedCallbackCache = Facades\Collection::getComputedCallbacks($this->collection); + } + + public function __serialize(): array + { + return Arr::except(get_object_vars($this), ['computedCallbackCache']); + } + + public function __unserialize(array $data): void + { + foreach ($data as $key => $value) { + $this->{$key} = $value; + } } } From 092e5d959e6639ec279bcc9d1863b725075e21e7 Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Mon, 1 Apr 2024 19:11:11 -0400 Subject: [PATCH 3/5] just use sleep --- src/Entries/Entry.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Entries/Entry.php b/src/Entries/Entry.php index d5815492fa0..97dd7e437bf 100644 --- a/src/Entries/Entry.php +++ b/src/Entries/Entry.php @@ -1028,7 +1028,7 @@ protected function getComputedCallbacks() return $this->computedCallbackCache = Facades\Collection::getComputedCallbacks($this->collection); } - public function __serialize(): array + public function __sleep() { if ($this->slug instanceof Closure) { $slug = $this->slug; @@ -1037,11 +1037,4 @@ public function __serialize(): array return Arr::except(get_object_vars($this), ['computedCallbackCache']); } - - public function __unserialize(array $data): void - { - foreach ($data as $key => $value) { - $this->{$key} = $value; - } - } } From 705b34a6a70da6a396bf7a3a93e985370e24ceb4 Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Mon, 1 Apr 2024 19:14:15 -0400 Subject: [PATCH 4/5] visibility --- src/Entries/Entry.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entries/Entry.php b/src/Entries/Entry.php index 97dd7e437bf..519af23c150 100644 --- a/src/Entries/Entry.php +++ b/src/Entries/Entry.php @@ -78,7 +78,7 @@ class Entry implements Arrayable, ArrayAccess, Augmentable, ContainsQueryableVal protected $withEvents = true; protected $template; protected $layout; - protected $computedCallbackCache; + private $computedCallbackCache; private $siteCache; public function __construct() From 2104ead8d909ffe38e7f211b5ae61e0353d57851 Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Mon, 1 Apr 2024 19:19:37 -0400 Subject: [PATCH 5/5] but do it right --- src/Entries/Entry.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entries/Entry.php b/src/Entries/Entry.php index 519af23c150..a31b44e26b2 100644 --- a/src/Entries/Entry.php +++ b/src/Entries/Entry.php @@ -1035,6 +1035,6 @@ public function __sleep() $this->slug = $slug($this); } - return Arr::except(get_object_vars($this), ['computedCallbackCache']); + return array_keys(Arr::except(get_object_vars($this), ['computedCallbackCache'])); } }