From 2923658bb9eb1885f4da84809b773e93fe67cb02 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 22 Dec 2020 15:12:09 +0200 Subject: [PATCH] Use PHP 7.4 serialization --- CHANGELOG.md | 2 + .../Collection/AbstractIndexCollection.php | 18 ++++---- .../Grav/Framework/Compat/Serializable.php | 16 +++++-- .../Framework/ContentBlock/ContentBlock.php | 17 +++++--- .../Grav/Framework/Flex/FlexDirectoryForm.php | 20 ++++----- system/src/Grav/Framework/Flex/FlexForm.php | 20 ++++----- system/src/Grav/Framework/Flex/FlexIndex.php | 12 +++--- .../Grav/Framework/Form/Traits/FormTrait.php | 43 +++++++++---------- .../Object/Base/ObjectCollectionTrait.php | 35 ++++++++------- .../Framework/Object/Base/ObjectTrait.php | 20 +++++---- 10 files changed, 106 insertions(+), 97 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46aa635e8..1c25a2f34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,10 @@ 1. [](#new) * Added support for overriding configuration by using environment variables + * Use PHP 7.4 serialization (the old `Serializable` methods are now final and cannot be overridden) 1. [](#improved) * Make it possible to use an absolute path when loading a blueprint + * Make serialize methods final in `ContentBlock`, `AbstractFile`, `FormTrait`, `ObjectCollectionTrait` and `ObjectTrait` 1. [](#bugfix) * Fixed port issue with `system.custom_base_url` * Hide errors with `exif_read_data` in `ImageFile` diff --git a/system/src/Grav/Framework/Collection/AbstractIndexCollection.php b/system/src/Grav/Framework/Collection/AbstractIndexCollection.php index 872f2fb14..21efa3056 100644 --- a/system/src/Grav/Framework/Collection/AbstractIndexCollection.php +++ b/system/src/Grav/Framework/Collection/AbstractIndexCollection.php @@ -11,6 +11,7 @@ namespace Grav\Framework\Collection; use ArrayIterator; use Closure; +use Grav\Framework\Compat\Serializable; use Grav\Framework\Flex\Interfaces\FlexObjectInterface; /** @@ -18,6 +19,8 @@ use Grav\Framework\Flex\Interfaces\FlexObjectInterface; */ abstract class AbstractIndexCollection implements CollectionInterface { + use Serializable; + /** * @var array */ @@ -418,22 +421,21 @@ abstract class AbstractIndexCollection implements CollectionInterface } /** - * @return string - * @return string + * @return array */ - public function serialize() + public function __serialize(): array { - return serialize(['entries' => $this->entries]); + return [ + 'entries' => $this->entries + ]; } /** - * @param string $serialized + * @param array $data * @return void */ - public function unserialize($serialized) + public function __unserialize(array $data): void { - $data = unserialize($serialized, ['allowed_classes' => false]); - $this->entries = $data['entries']; } diff --git a/system/src/Grav/Framework/Compat/Serializable.php b/system/src/Grav/Framework/Compat/Serializable.php index 9883d7a93..35bbfbe59 100644 --- a/system/src/Grav/Framework/Compat/Serializable.php +++ b/system/src/Grav/Framework/Compat/Serializable.php @@ -21,9 +21,9 @@ namespace Grav\Framework\Compat; trait Serializable { /** - * @return string|null + * @return string */ - public function serialize(): ?string + final public function serialize(): string { return serialize($this->__serialize()); } @@ -32,8 +32,16 @@ trait Serializable * @param string $serialized * @return void */ - public function unserialize($serialized): void + final public function unserialize($serialized): void { - $this->__unserialize(unserialize($serialized, ['allowed_classes' => false])); + $this->__unserialize(unserialize($serialized, ['allowed_classes' => $this->getUnserializeAllowedClasses()])); + } + + /** + * @return array|bool + */ + protected function getUnserializeAllowedClasses() + { + return false; } } diff --git a/system/src/Grav/Framework/ContentBlock/ContentBlock.php b/system/src/Grav/Framework/ContentBlock/ContentBlock.php index 4c24bdc12..ef9173ded 100644 --- a/system/src/Grav/Framework/ContentBlock/ContentBlock.php +++ b/system/src/Grav/Framework/ContentBlock/ContentBlock.php @@ -9,6 +9,8 @@ namespace Grav\Framework\ContentBlock; +use Grav\Framework\Compat\Serializable; + /** * Class to create nested blocks of content. * @@ -23,6 +25,8 @@ namespace Grav\Framework\ContentBlock; */ class ContentBlock implements ContentBlockInterface { + use Serializable; + /** @var int */ protected $version = 1; /** @var string */ @@ -255,21 +259,20 @@ class ContentBlock implements ContentBlockInterface } /** - * @return string + * @return array */ - public function serialize() + final public function __serialize(): array { - return serialize($this->toArray()); + return $this->toArray(); } /** - * @param string $serialized + * @param array $data * @return void */ - public function unserialize($serialized) + final public function __unserialize(array $data): void { - $array = unserialize($serialized); - $this->build($array); + $this->build($data); } /** diff --git a/system/src/Grav/Framework/Flex/FlexDirectoryForm.php b/system/src/Grav/Framework/Flex/FlexDirectoryForm.php index fcb5225a4..031cda293 100644 --- a/system/src/Grav/Framework/Flex/FlexDirectoryForm.php +++ b/system/src/Grav/Framework/Flex/FlexDirectoryForm.php @@ -335,18 +335,6 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, \JsonSerializable return ''; } - /** - * Implements \Serializable::unserialize(). - * - * @param string $data - */ - public function unserialize($data): void - { - $data = unserialize($data, ['allowed_classes' => [FlexObject::class]]); - - $this->doUnserialize($data); - } - /** * @param string $name * @return mixed|null @@ -400,6 +388,14 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, \JsonSerializable { } + /** + * @return array|bool + */ + protected function getUnserializeAllowedClasses() + { + return [FlexObject::class]; + } + /** * Note: this method clones the object. * diff --git a/system/src/Grav/Framework/Flex/FlexForm.php b/system/src/Grav/Framework/Flex/FlexForm.php index 13a72a260..a7b785475 100644 --- a/system/src/Grav/Framework/Flex/FlexForm.php +++ b/system/src/Grav/Framework/Flex/FlexForm.php @@ -393,18 +393,6 @@ class FlexForm implements FlexObjectFormInterface, \JsonSerializable return ''; } - /** - * Implements \Serializable::unserialize(). - * - * @param string $data - */ - public function unserialize($data): void - { - $data = unserialize($data, ['allowed_classes' => [FlexObject::class]]); - - $this->doUnserialize($data); - } - /** * @param string $name * @return mixed|null @@ -458,6 +446,14 @@ class FlexForm implements FlexObjectFormInterface, \JsonSerializable { } + /** + * @return array|bool + */ + protected function getUnserializeAllowedClasses() + { + return [FlexObject::class]; + } + /** * Note: this method clones the object. * diff --git a/system/src/Grav/Framework/Flex/FlexIndex.php b/system/src/Grav/Framework/Flex/FlexIndex.php index ccd1e5882..6d67115e2 100644 --- a/system/src/Grav/Framework/Flex/FlexIndex.php +++ b/system/src/Grav/Framework/Flex/FlexIndex.php @@ -487,21 +487,19 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde } /** - * @return string + * @return array */ - public function serialize() + public function __serialize(): array { - return serialize(['type' => $this->getFlexType(), 'entries' => $this->getEntries()]); + return ['type' => $this->getFlexType(), 'entries' => $this->getEntries()]; } /** - * @param string $serialized + * @param array $data * @return void */ - public function unserialize($serialized) + public function __unserialize(array $data): void { - $data = unserialize($serialized, ['allowed_classes' => false]); - $this->_flexDirectory = Grav::instance()['flex']->getDirectory($data['type']); $this->setEntries($data['entries']); } diff --git a/system/src/Grav/Framework/Form/Traits/FormTrait.php b/system/src/Grav/Framework/Form/Traits/FormTrait.php index 81ae4add6..0d93f8a44 100644 --- a/system/src/Grav/Framework/Form/Traits/FormTrait.php +++ b/system/src/Grav/Framework/Form/Traits/FormTrait.php @@ -18,6 +18,7 @@ use Grav\Common\Grav; use Grav\Common\Twig\Twig; use Grav\Common\User\Interfaces\UserInterface; use Grav\Common\Utils; +use Grav\Framework\Compat\Serializable; use Grav\Framework\ContentBlock\HtmlBlock; use Grav\Framework\Form\Interfaces\FormFlashInterface; use Grav\Framework\Form\Interfaces\FormInterface; @@ -35,6 +36,8 @@ use Twig\TemplateWrapper; */ trait FormTrait { + use Serializable; + /** @var string */ public $status = 'success'; /** @var string|null */ @@ -402,29 +405,6 @@ trait FormTrait */ abstract public function getBlueprint(): Blueprint; - /** - * Implements \Serializable::serialize(). - * - * @return string - */ - public function serialize(): string - { - return serialize($this->doSerialize()); - } - - /** - * Implements \Serializable::unserialize(). - * - * @param string $serialized - * @return void - */ - public function unserialize($serialized): void - { - $data = unserialize($serialized, ['allowed_classes' => false]); - - $this->doUnserialize($data); - } - /** * Get form flash object. * @@ -514,6 +494,23 @@ trait FormTrait return $this->doSerialize(); } + /** + * @return array + */ + final public function __serialize(): array + { + return $this->doSerialize(); + } + + /** + * @param array $data + * @return void + */ + final public function __unserialize(array $data): void + { + $this->doUnserialize($data); + } + protected function getSessionId(): string { if (null === $this->sessionid) { diff --git a/system/src/Grav/Framework/Object/Base/ObjectCollectionTrait.php b/system/src/Grav/Framework/Object/Base/ObjectCollectionTrait.php index 07179c6be..5841a6bcf 100644 --- a/system/src/Grav/Framework/Object/Base/ObjectCollectionTrait.php +++ b/system/src/Grav/Framework/Object/Base/ObjectCollectionTrait.php @@ -9,6 +9,7 @@ namespace Grav\Framework\Object\Base; +use Grav\Framework\Compat\Serializable; use Grav\Framework\Object\Interfaces\ObjectInterface; /** @@ -17,6 +18,8 @@ use Grav\Framework\Object\Interfaces\ObjectInterface; */ trait ObjectCollectionTrait { + use Serializable; + /** @var string */ protected static $type; @@ -120,49 +123,51 @@ trait ObjectCollectionTrait } /** - * Implements Serializable interface. - * - * @return string + * @return array */ - public function serialize() + final public function __serialize(): array { - return serialize($this->doSerialize()); + return $this->doSerialize(); } /** - * @param string $serialized + * @param array $data * @return void */ - public function unserialize($serialized) + final public function __unserialize(array $data): void { - $data = unserialize($serialized); - if (method_exists($this, 'initObjectProperties')) { $this->initObjectProperties(); } + $this->doUnserialize($data); } + /** * @return array */ protected function doSerialize() { - return ['key' => $this->getKey(), 'type' => $this->getType(), 'elements' => $this->getElements()]; + return [ + 'key' => $this->getKey(), + 'type' => $this->getType(), + 'elements' => $this->getElements() + ]; } /** - * @param array $serialized + * @param array $data * @return void */ - protected function doUnserialize(array $serialized) + protected function doUnserialize(array $data) { - if (!isset($serialized['key'], $serialized['type'], $serialized['elements']) || $serialized['type'] !== $this->getType()) { + if (!isset($data['key'], $data['type'], $data['elements']) || $data['type'] !== $this->getType()) { throw new \InvalidArgumentException("Cannot unserialize '{$this->getType()}': Bad data"); } - $this->setKey($serialized['key']); - $this->setElements($serialized['elements']); + $this->setKey($data['key']); + $this->setElements($data['elements']); } /** diff --git a/system/src/Grav/Framework/Object/Base/ObjectTrait.php b/system/src/Grav/Framework/Object/Base/ObjectTrait.php index 388aad8b0..4af4c2f1a 100644 --- a/system/src/Grav/Framework/Object/Base/ObjectTrait.php +++ b/system/src/Grav/Framework/Object/Base/ObjectTrait.php @@ -9,6 +9,8 @@ namespace Grav\Framework\Object\Base; +use Grav\Framework\Compat\Serializable; + /** * Object trait. * @@ -16,6 +18,8 @@ namespace Grav\Framework\Object\Base; */ trait ObjectTrait { + use Serializable; + /** @var string */ protected static $type; @@ -119,25 +123,23 @@ trait ObjectTrait } /** - * Implements Serializable interface. - * - * @return string + * @return array */ - public function serialize() + final public function __serialize(): array { - return serialize($this->doSerialize()); + return $this->doSerialize(); } /** - * @param string $serialized + * @param array $data + * @return void */ - public function unserialize($serialized) + final public function __unserialize(array $data): void { - $data = unserialize($serialized); - if (method_exists($this, 'initObjectProperties')) { $this->initObjectProperties(); } + $this->doUnserialize($data); }