Browse Source

Add __serialize()/__unserialize() magic methods.

The Serializable interface is deprecated in PHP 8.1 and adding these methods
avoids deprecation errors.
ADmad 4 years ago
parent
commit
9697c130c6

+ 21 - 0
src/Collection/Collection.php

@@ -55,6 +55,16 @@ class Collection extends IteratorIterator implements CollectionInterface, Serial
     }
 
     /**
+     * Returns an array for serializing this of this object.
+     *
+     * @return array
+     */
+    public function __serialize(): array
+    {
+        return $this->buffered()->toArray();
+    }
+
+    /**
      * Unserializes the passed string and rebuilds the Collection instance
      *
      * @param string $collection The serialized collection
@@ -66,6 +76,17 @@ class Collection extends IteratorIterator implements CollectionInterface, Serial
     }
 
     /**
+     * Rebuilds the Collection instance.
+     *
+     * @param array $data Data array.
+     * @return void
+     */
+    public function __unserialize(array $data): void
+    {
+        $this->__construct($data);
+    }
+
+    /**
      * {@inheritDoc}
      *
      * @return int

+ 32 - 0
src/Collection/Iterator/BufferedIterator.php

@@ -202,6 +202,20 @@ class BufferedIterator extends Collection implements Countable, Serializable
     }
 
     /**
+     * Magic method used for serializing the iterator instance.
+     *
+     * @return array
+     */
+    public function __serialize(): array
+    {
+        if (!$this->_finished) {
+            $this->count();
+        }
+
+        return iterator_to_array($this->_buffer);
+    }
+
+    /**
      * Unserializes the passed string and rebuilds the BufferedIterator instance
      *
      * @param string $buffer The serialized buffer iterator
@@ -214,4 +228,22 @@ class BufferedIterator extends Collection implements Countable, Serializable
         $this->_started = true;
         $this->_finished = true;
     }
+
+    /**
+     * Magic method used to rebuild the iterator instance.
+     *
+     * @param array $data Data array.
+     * @return void
+     */
+    public function __unserialize(array $data): void
+    {
+        $this->__construct([]);
+
+        foreach ($data as $value) {
+            $this->_buffer->push($value);
+        }
+
+        $this->_started = true;
+        $this->_finished = true;
+    }
 }

+ 26 - 0
src/Collection/Iterator/ZipIterator.php

@@ -111,6 +111,16 @@ class ZipIterator extends MultipleIterator implements CollectionInterface, Seria
     }
 
     /**
+     * Magic method used for serializing the iterator instance.
+     *
+     * @return array
+     */
+    public function __serialize(): array
+    {
+        return $this->_iterators;
+    }
+
+    /**
      * Unserializes the passed string and rebuilds the ZipIterator instance
      *
      * @param string $iterators The serialized iterators
@@ -124,4 +134,20 @@ class ZipIterator extends MultipleIterator implements CollectionInterface, Seria
             $this->attachIterator($it);
         }
     }
+
+    /**
+     * Magic method used to rebuild the iterator instance.
+     *
+     * @param array $data Data array.
+     * @return void
+     */
+    public function __unserialize(array $data): void
+    {
+        parent::__construct(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_NUMERIC);
+
+        $this->_iterators = $data;
+        foreach ($this->_iterators as $it) {
+            $this->attachIterator($it);
+        }
+    }
 }

+ 9 - 4
src/Log/Engine/BaseLog.php

@@ -140,13 +140,18 @@ abstract class BaseLog extends AbstractLogger
             }
 
             if (is_object($value)) {
-                if (method_exists($value, '__toString')) {
-                    $replacements['{' . $key . '}'] = (string)$value;
+                if (method_exists($value, 'toArray')) {
+                    $replacements['{' . $key . '}'] = json_encode($value->toArray(), JSON_UNESCAPED_UNICODE);
                     continue;
                 }
 
-                if (method_exists($value, 'toArray')) {
-                    $replacements['{' . $key . '}'] = json_encode($value->toArray(), JSON_UNESCAPED_UNICODE);
+                if (method_exists($value, '__serialize')) {
+                    $replacements['{' . $key . '}'] = serialize($value);
+                    continue;
+                }
+
+                if (method_exists($value, '__toString')) {
+                    $replacements['{' . $key . '}'] = (string)$value;
                     continue;
                 }
 

+ 24 - 1
src/Mailer/Email.php

@@ -586,6 +586,18 @@ class Email implements JsonSerializable, Serializable
      */
     public function serialize(): string
     {
+        $array = $this->__serialize();
+
+        return serialize($array);
+    }
+
+    /**
+     * Magic method used for serializing the Email object.
+     *
+     * @return array
+     */
+    public function __serialize(): array
+    {
         $array = $this->jsonSerialize();
         array_walk_recursive($array, function (&$item, $key): void {
             if ($item instanceof SimpleXMLElement) {
@@ -593,7 +605,7 @@ class Email implements JsonSerializable, Serializable
             }
         });
 
-        return serialize($array);
+        return $array;
     }
 
     /**
@@ -608,6 +620,17 @@ class Email implements JsonSerializable, Serializable
     }
 
     /**
+     * Magic method used to rebuild the Email object.
+     *
+     * @param array $data Data array.
+     * @return void
+     */
+    public function __unserialize(array $data): void
+    {
+        $this->createFromArray($data);
+    }
+
+    /**
      * Proxy all static method calls (for methods provided by StaticConfigTrait) to Mailer.
      *
      * @param string $name Method name.

+ 24 - 1
src/Mailer/Message.php

@@ -1895,6 +1895,18 @@ class Message implements JsonSerializable, Serializable
      */
     public function serialize(): string
     {
+        $array = $this->__serialize();
+
+        return serialize($array);
+    }
+
+    /**
+     * Magic method used for serializing the Message object.
+     *
+     * @return array
+     */
+    public function __serialize(): array
+    {
         $array = $this->jsonSerialize();
         array_walk_recursive($array, function (&$item, $key): void {
             if ($item instanceof SimpleXMLElement) {
@@ -1902,7 +1914,7 @@ class Message implements JsonSerializable, Serializable
             }
         });
 
-        return serialize($array);
+        return $array;
     }
 
     /**
@@ -1920,4 +1932,15 @@ class Message implements JsonSerializable, Serializable
 
         $this->createFromArray($array);
     }
+
+    /**
+     * Magic method used to rebuild the Message object.
+     *
+     * @param array $data Data array.
+     * @return void
+     */
+    public function __unserialize(array $data): void
+    {
+        $this->createFromArray($data);
+    }
 }

+ 24 - 4
src/ORM/ResultSet.php

@@ -299,6 +299,16 @@ class ResultSet implements ResultSetInterface
      */
     public function serialize(): string
     {
+        return serialize($this->__serialize());
+    }
+
+    /**
+     * Serializes a resultset.
+     *
+     * @return array
+     */
+    public function __serialize(): array
+    {
         if (!$this->_useBuffering) {
             $msg = 'You cannot serialize an un-buffered ResultSet. '
                 . 'Use Query::bufferResults() to get a buffered ResultSet.';
@@ -310,10 +320,10 @@ class ResultSet implements ResultSetInterface
         }
 
         if ($this->_results instanceof SplFixedArray) {
-            return serialize($this->_results->toArray());
+            return $this->_results->toArray();
         }
 
-        return serialize($this->_results);
+        return $this->_results;
     }
 
     /**
@@ -326,8 +336,18 @@ class ResultSet implements ResultSetInterface
      */
     public function unserialize($serialized)
     {
-        $results = (array)(unserialize($serialized) ?: []);
-        $this->_results = SplFixedArray::fromArray($results);
+        $this->__unserialize((array)(unserialize($serialized) ?: []));
+    }
+
+    /**
+     * Unserializes a resultset.
+     *
+     * @param array $data Data array.
+     * @return void
+     */
+    public function __unserialize(array $data): void
+    {
+        $this->_results = SplFixedArray::fromArray($data);
         $this->_useBuffering = true;
         $this->_count = $this->_results->count();
     }

+ 21 - 0
src/View/ViewBuilder.php

@@ -663,6 +663,16 @@ class ViewBuilder implements JsonSerializable, Serializable
     }
 
     /**
+     * Magic method used for serializing the view builder object.
+     *
+     * @return array
+     */
+    public function __serialize(): array
+    {
+        return $this->jsonSerialize();
+    }
+
+    /**
      * Unserializes the view builder object.
      *
      * @param string $data Serialized string.
@@ -672,4 +682,15 @@ class ViewBuilder implements JsonSerializable, Serializable
     {
         $this->createFromArray(unserialize($data));
     }
+
+    /**
+     * Magic method used to rebuild the view builder object.
+     *
+     * @param array $data Data array.
+     * @return void
+     */
+    public function __unserialize(array $data): void
+    {
+        $this->createFromArray($data);
+    }
 }

+ 21 - 0
tests/TestCase/Collection/Iterator/BufferedIteratorTest.php

@@ -90,4 +90,25 @@ class BufferedIteratorTest extends TestCase
         }
         $this->assertEquals([1, 2, 3], $result);
     }
+
+    /**
+     * Testing serialize and unserialize features.
+     *
+     * @return void
+     */
+    public function testSerialization()
+    {
+        $items = new ArrayObject([
+            'a' => 1,
+            'b' => 2,
+            'c' => 3,
+        ]);
+        $expected = (array)$items;
+
+        $iterator = new BufferedIterator($items);
+
+        $serialized = serialize($iterator);
+        $outcome = unserialize($serialized);
+        $this->assertEquals($expected, $outcome->toArray());
+    }
 }