Browse Source

Add ViewBuilder serializer.

This helps serialiazing Email objects along with config for view.
ADmad 10 years ago
parent
commit
4eecd3a901

+ 10 - 5
src/Mailer/Email.php

@@ -1891,12 +1891,12 @@ class Email implements JsonSerializable, Serializable
     public function jsonSerialize()
     {
         $properties = [
-            '_to', '_from', '_sender', '_replyTo', '_cc', '_bcc', '_subject', '_returnPath', '_readReceipt',
-            '_template', '_layout', '_viewRender', '_viewVars', '_theme', '_helpers', '_emailFormat',
-            '_emailPattern', '_attachments', '_domain', '_messageId', '_headers', 'charset', 'headerCharset',
+            '_to', '_from', '_sender', '_replyTo', '_cc', '_bcc', '_subject',
+            '_returnPath', '_readReceipt', '_emailFormat', '_emailPattern', '_domain',
+            '_attachments', '_messageId', '_headers', 'viewVars', 'charset', 'headerCharset'
         ];
 
-        $array = [];
+        $array = ['viewConfig' => $this->viewBuilder()->jsonSerialize()];
 
         foreach ($properties as $property) {
             $array[$property] = $this->{$property};
@@ -1909,7 +1909,7 @@ class Email implements JsonSerializable, Serializable
             }
         });
 
-        array_walk_recursive($array['_viewVars'], [$this, '_checkViewVars']);
+        array_walk_recursive($array['viewVars'], [$this, '_checkViewVars']);
 
         return array_filter($array, function ($i) {
             return !is_array($i) && strlen($i) || !empty($i);
@@ -1950,6 +1950,11 @@ class Email implements JsonSerializable, Serializable
      */
     public function createFromArray($config)
     {
+        if (isset($config['viewConfig'])) {
+            $this->viewBuilder()->createFromArray($config['viewConfig']);
+            unset($config['viewConfig']);
+        }
+
         foreach ($config as $property => $value) {
             $this->{$property} = $value;
         }

+ 64 - 1
src/View/ViewBuilder.php

@@ -20,6 +20,8 @@ use Cake\Network\Request;
 use Cake\Network\Response;
 use Cake\View\Exception\MissingViewException;
 use Cake\View\View;
+use JsonSerializable;
+use Serializable;
 
 /**
  * Provides an API for iteratively building a view up.
@@ -27,7 +29,7 @@ use Cake\View\View;
  * Once you have configured the view and established all the context
  * you can create a view instance with `build()`.
  */
-class ViewBuilder
+class ViewBuilder implements JsonSerializable, Serializable
 {
     /**
      * The subdirectory to the template.
@@ -338,4 +340,65 @@ class ViewBuilder
         $data += $this->_options;
         return new $className($request, $response, $events, $data);
     }
+
+    /**
+     * Serializes the view builder object to a value that can be natively
+     * serialized and re-used to clone this builder instance.
+     *
+     * @return array Serializable array of configuration properties.
+     */
+    public function jsonSerialize()
+    {
+        $properties = [
+            '_templatePath', '_template', '_plugin', '_theme', '_layout', '_autoLayout',
+            '_layoutPath', '_name', '_className', '_options', '_helpers'
+        ];
+
+        $array = [];
+
+        foreach ($properties as $property) {
+            $array[$property] = $this->{$property};
+        }
+
+        return array_filter($array, function ($i) {
+            return !is_array($i) && strlen($i) || !empty($i);
+        });
+    }
+
+    /**
+     * Configures a view builder instance from serialized config.
+     *
+     * @param array $config View builder configuration array.
+     * @return $this Configured view builder instance.
+     */
+    public function createFromArray($config)
+    {
+        foreach ($config as $property => $value) {
+            $this->{$property} = $value;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Serializes the view builder object.
+     *
+     * @return void
+     */
+    public function serialize()
+    {
+        $array = $this->jsonSerialize();
+        return serialize($array);
+    }
+
+    /**
+     * Unserializes the view builder object.
+     *
+     * @param string $data Serialized string.
+     * @return $this Configured view builder instance.
+     */
+    public function unserialize($data)
+    {
+        return $this->createFromArray(unserialize($data));
+    }
 }

+ 15 - 11
tests/TestCase/Mailer/EmailTest.php

@@ -2648,7 +2648,6 @@ XML;
             ->cc(['mark@cakephp.org', 'juan@cakephp.org' => 'Juan Basso'])
             ->bcc('phpnut@cakephp.org')
             ->subject('Test Serialize')
-            ->template('default', 'test')
             ->messageId('<uuid@server.com>')
             ->domain('foo.bar')
             ->viewVars([
@@ -2664,9 +2663,13 @@ XML;
                 ]
             ]);
 
+        $this->CakeEmail->viewBuilder()
+            ->template('default')
+            ->layout('test');
+
         $result = json_decode(json_encode($this->CakeEmail), true);
-        $this->assertContains('test', $result['_viewVars']['exception']);
-        unset($result['_viewVars']['exception']);
+        $this->assertContains('test', $result['viewVars']['exception']);
+        unset($result['viewVars']['exception']);
 
         $encode = function ($path) {
             return chunk_split(base64_encode(file_get_contents($path)), 76, "\r\n");
@@ -2679,16 +2682,18 @@ XML;
             '_cc' => ['mark@cakephp.org' => 'mark@cakephp.org', 'juan@cakephp.org' => 'Juan Basso'],
             '_bcc' => ['phpnut@cakephp.org' => 'phpnut@cakephp.org'],
             '_subject' => 'Test Serialize',
-            '_template' => 'default',
-            '_layout' => 'test',
-            '_viewRender' => 'Cake\View\View',
-            '_helpers' => ['Html'],
             '_emailFormat' => 'text',
             '_messageId' => '<uuid@server.com>',
             '_domain' => 'foo.bar',
             'charset' => 'utf-8',
             'headerCharset' => 'utf-8',
-            '_viewVars' => [
+            'viewConfig' => [
+                '_template' => 'default',
+                '_layout' => 'test',
+                '_helpers' => ['Html'],
+                '_className' => 'Cake\View\View',
+            ],
+            'viewVars' => [
                 'users' => [
                     'id' => 1,
                     'username' => 'mariano'
@@ -2712,10 +2717,9 @@ XML;
         ];
         $this->assertEquals($expected, $result);
 
-        debug(unserialize(serialize($this->CakeEmail)));
         $result = json_decode(json_encode(unserialize(serialize($this->CakeEmail))), true);
-        $this->assertContains('test', $result['_viewVars']['exception']);
-        unset($result['_viewVars']['exception']);
+        $this->assertContains('test', $result['viewVars']['exception']);
+        unset($result['viewVars']['exception']);
         $this->assertEquals($expected, $result);
     }
 

+ 29 - 0
tests/TestCase/View/ViewBuilderTest.php

@@ -183,4 +183,33 @@ class ViewBuilderTest extends TestCase
         $builder->className('Foo');
         $builder->build();
     }
+
+    /**
+     * testJsonSerialize()
+     *
+     * @return void
+     */
+    public function testJsonSerialize()
+    {
+        $builder = new ViewBuilder();
+
+        $builder
+            ->template('default')
+            ->layout('test')
+            ->helpers(['Html'])
+            ->className('JsonView');
+
+        $result = json_decode(json_encode($builder), true);
+
+        $expected = [
+            '_template' => 'default',
+            '_layout' => 'test',
+            '_helpers' => ['Html'],
+            '_className' => 'JsonView',
+        ];
+        $this->assertEquals($expected, $result);
+
+        $result = json_decode(json_encode(unserialize(serialize($builder))), true);
+        $this->assertEquals($expected, $result);
+    }
 }