Use PHP 7.4 serialization

This commit is contained in:
Matias Griese
2020-12-22 15:12:09 +02:00
parent c333da60d6
commit 2923658bb9
10 changed files with 106 additions and 97 deletions

View File

@@ -3,8 +3,10 @@
1. [](#new) 1. [](#new)
* Added support for overriding configuration by using environment variables * 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) 1. [](#improved)
* Make it possible to use an absolute path when loading a blueprint * 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) 1. [](#bugfix)
* Fixed port issue with `system.custom_base_url` * Fixed port issue with `system.custom_base_url`
* Hide errors with `exif_read_data` in `ImageFile` * Hide errors with `exif_read_data` in `ImageFile`

View File

@@ -11,6 +11,7 @@ namespace Grav\Framework\Collection;
use ArrayIterator; use ArrayIterator;
use Closure; use Closure;
use Grav\Framework\Compat\Serializable;
use Grav\Framework\Flex\Interfaces\FlexObjectInterface; use Grav\Framework\Flex\Interfaces\FlexObjectInterface;
/** /**
@@ -18,6 +19,8 @@ use Grav\Framework\Flex\Interfaces\FlexObjectInterface;
*/ */
abstract class AbstractIndexCollection implements CollectionInterface abstract class AbstractIndexCollection implements CollectionInterface
{ {
use Serializable;
/** /**
* @var array * @var array
*/ */
@@ -418,22 +421,21 @@ abstract class AbstractIndexCollection implements CollectionInterface
} }
/** /**
* @return string * @return array
* @return string
*/ */
public function serialize() public function __serialize(): array
{ {
return serialize(['entries' => $this->entries]); return [
'entries' => $this->entries
];
} }
/** /**
* @param string $serialized * @param array $data
* @return void * @return void
*/ */
public function unserialize($serialized) public function __unserialize(array $data): void
{ {
$data = unserialize($serialized, ['allowed_classes' => false]);
$this->entries = $data['entries']; $this->entries = $data['entries'];
} }

View File

@@ -21,9 +21,9 @@ namespace Grav\Framework\Compat;
trait Serializable trait Serializable
{ {
/** /**
* @return string|null * @return string
*/ */
public function serialize(): ?string final public function serialize(): string
{ {
return serialize($this->__serialize()); return serialize($this->__serialize());
} }
@@ -32,8 +32,16 @@ trait Serializable
* @param string $serialized * @param string $serialized
* @return void * @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;
} }
} }

View File

@@ -9,6 +9,8 @@
namespace Grav\Framework\ContentBlock; namespace Grav\Framework\ContentBlock;
use Grav\Framework\Compat\Serializable;
/** /**
* Class to create nested blocks of content. * Class to create nested blocks of content.
* *
@@ -23,6 +25,8 @@ namespace Grav\Framework\ContentBlock;
*/ */
class ContentBlock implements ContentBlockInterface class ContentBlock implements ContentBlockInterface
{ {
use Serializable;
/** @var int */ /** @var int */
protected $version = 1; protected $version = 1;
/** @var string */ /** @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 * @return void
*/ */
public function unserialize($serialized) final public function __unserialize(array $data): void
{ {
$array = unserialize($serialized); $this->build($data);
$this->build($array);
} }
/** /**

View File

@@ -335,18 +335,6 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, \JsonSerializable
return ''; 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 * @param string $name
* @return mixed|null * @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. * Note: this method clones the object.
* *

View File

@@ -393,18 +393,6 @@ class FlexForm implements FlexObjectFormInterface, \JsonSerializable
return ''; 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 * @param string $name
* @return mixed|null * @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. * Note: this method clones the object.
* *

View File

@@ -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 * @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->_flexDirectory = Grav::instance()['flex']->getDirectory($data['type']);
$this->setEntries($data['entries']); $this->setEntries($data['entries']);
} }

View File

@@ -18,6 +18,7 @@ use Grav\Common\Grav;
use Grav\Common\Twig\Twig; use Grav\Common\Twig\Twig;
use Grav\Common\User\Interfaces\UserInterface; use Grav\Common\User\Interfaces\UserInterface;
use Grav\Common\Utils; use Grav\Common\Utils;
use Grav\Framework\Compat\Serializable;
use Grav\Framework\ContentBlock\HtmlBlock; use Grav\Framework\ContentBlock\HtmlBlock;
use Grav\Framework\Form\Interfaces\FormFlashInterface; use Grav\Framework\Form\Interfaces\FormFlashInterface;
use Grav\Framework\Form\Interfaces\FormInterface; use Grav\Framework\Form\Interfaces\FormInterface;
@@ -35,6 +36,8 @@ use Twig\TemplateWrapper;
*/ */
trait FormTrait trait FormTrait
{ {
use Serializable;
/** @var string */ /** @var string */
public $status = 'success'; public $status = 'success';
/** @var string|null */ /** @var string|null */
@@ -402,29 +405,6 @@ trait FormTrait
*/ */
abstract public function getBlueprint(): Blueprint; 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. * Get form flash object.
* *
@@ -514,6 +494,23 @@ trait FormTrait
return $this->doSerialize(); 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 protected function getSessionId(): string
{ {
if (null === $this->sessionid) { if (null === $this->sessionid) {

View File

@@ -9,6 +9,7 @@
namespace Grav\Framework\Object\Base; namespace Grav\Framework\Object\Base;
use Grav\Framework\Compat\Serializable;
use Grav\Framework\Object\Interfaces\ObjectInterface; use Grav\Framework\Object\Interfaces\ObjectInterface;
/** /**
@@ -17,6 +18,8 @@ use Grav\Framework\Object\Interfaces\ObjectInterface;
*/ */
trait ObjectCollectionTrait trait ObjectCollectionTrait
{ {
use Serializable;
/** @var string */ /** @var string */
protected static $type; protected static $type;
@@ -120,49 +123,51 @@ trait ObjectCollectionTrait
} }
/** /**
* Implements Serializable interface. * @return array
*
* @return string
*/ */
public function serialize() final public function __serialize(): array
{ {
return serialize($this->doSerialize()); return $this->doSerialize();
} }
/** /**
* @param string $serialized * @param array $data
* @return void * @return void
*/ */
public function unserialize($serialized) final public function __unserialize(array $data): void
{ {
$data = unserialize($serialized);
if (method_exists($this, 'initObjectProperties')) { if (method_exists($this, 'initObjectProperties')) {
$this->initObjectProperties(); $this->initObjectProperties();
} }
$this->doUnserialize($data); $this->doUnserialize($data);
} }
/** /**
* @return array * @return array
*/ */
protected function doSerialize() 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 * @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"); throw new \InvalidArgumentException("Cannot unserialize '{$this->getType()}': Bad data");
} }
$this->setKey($serialized['key']); $this->setKey($data['key']);
$this->setElements($serialized['elements']); $this->setElements($data['elements']);
} }
/** /**

View File

@@ -9,6 +9,8 @@
namespace Grav\Framework\Object\Base; namespace Grav\Framework\Object\Base;
use Grav\Framework\Compat\Serializable;
/** /**
* Object trait. * Object trait.
* *
@@ -16,6 +18,8 @@ namespace Grav\Framework\Object\Base;
*/ */
trait ObjectTrait trait ObjectTrait
{ {
use Serializable;
/** @var string */ /** @var string */
protected static $type; protected static $type;
@@ -119,25 +123,23 @@ trait ObjectTrait
} }
/** /**
* Implements Serializable interface. * @return array
*
* @return string
*/ */
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')) { if (method_exists($this, 'initObjectProperties')) {
$this->initObjectProperties(); $this->initObjectProperties();
} }
$this->doUnserialize($data); $this->doUnserialize($data);
} }