Browse Source

Update Response to use CookieCollection internally.

This change should be completely backwards compatible and enable the new
cookie collection to be used.
Mark Story 9 years ago
parent
commit
bf81b15169
2 changed files with 74 additions and 22 deletions
  1. 47 13
      src/Http/Response.php
  2. 27 9
      tests/TestCase/Http/ResponseTest.php

+ 47 - 13
src/Http/Response.php

@@ -16,6 +16,8 @@ namespace Cake\Http;
 
 use Cake\Core\Configure;
 use Cake\Filesystem\File;
+use Cake\Http\Cookie\Cookie;
+use Cake\Http\Cookie\CookieCollection;
 use Cake\Log\Log;
 use Cake\Network\CorsBuilder;
 use Cake\Network\Exception\NotFoundException;
@@ -389,11 +391,11 @@ class Response implements ResponseInterface
     protected $_cacheDirectives = [];
 
     /**
-     * Holds cookies to be sent to the client
+     * Collection of cookies to send to the client
      *
-     * @var array
+     * @var Cake\Http\Cookie\CookieCollection
      */
-    protected $_cookies = [];
+    protected $_cookies = null;
 
     /**
      * Reason Phrase
@@ -459,6 +461,7 @@ class Response implements ResponseInterface
             $this->_contentType = $this->resolveType($options['type']);
         }
         $this->_setContentType();
+        $this->_cookies = new CookieCollection();
     }
 
     /**
@@ -1928,15 +1931,15 @@ class Response implements ResponseInterface
     public function cookie($options = null)
     {
         if ($options === null) {
-            return $this->_cookies;
+            return $this->getCookies();
         }
 
         if (is_string($options)) {
-            if (!isset($this->_cookies[$options])) {
+            if (!$this->_cookies->has($options)) {
                 return null;
             }
 
-            return $this->_cookies[$options];
+            return $this->_cookies->get($options)->toArrayResponse();
         }
 
         $defaults = [
@@ -1949,8 +1952,16 @@ class Response implements ResponseInterface
             'httpOnly' => false
         ];
         $options += $defaults;
-
-        $this->_cookies[$options['name']] = $options;
+        $cookie = new Cookie(
+            $options['name'],
+            $options['value'],
+            $options['expire'],
+            $options['path'],
+            $options['domain'],
+            $options['secure'],
+            $options['httpOnly']
+        );
+        $this->_cookies = $this->_cookies->add($cookie);
     }
 
     /**
@@ -1994,10 +2005,18 @@ class Response implements ResponseInterface
             'httpOnly' => false
         ];
         $data += $defaults;
-        $data['name'] = $name;
+        $cookie = new Cookie(
+            $name,
+            $data['value'],
+            $data['expire'],
+            $data['path'],
+            $data['domain'],
+            $data['secure'],
+            $data['httpOnly']
+        );
 
         $new = clone $this;
-        $new->_cookies[$name] = $data;
+        $new->_cookies = $new->_cookies->add($cookie);
 
         return $new;
     }
@@ -2013,11 +2032,11 @@ class Response implements ResponseInterface
      */
     public function getCookie($name)
     {
-        if (isset($this->_cookies[$name])) {
-            return $this->_cookies[$name];
+        if (!$this->_cookies->has($name)) {
+            return null;
         }
 
-        return null;
+        return $this->_cookies->get($name)->toArrayResponse();
     }
 
     /**
@@ -2029,6 +2048,21 @@ class Response implements ResponseInterface
      */
     public function getCookies()
     {
+        $out = [];
+        foreach ($this->_cookies as $cookie) {
+            $out[$cookie->getName()] = $cookie->toArrayResponse();
+        }
+
+        return $out;
+    }
+
+    /**
+     * Get the CookieCollection from the response
+     *
+     * @return \Cake\Http\Cookie\CookieCollection
+     */
+    public function getCookieCollection()
+    {
         return $this->_cookies;
     }
 

+ 27 - 9
tests/TestCase/Http/ResponseTest.php

@@ -16,6 +16,8 @@ namespace Cake\Test\TestCase\Http;
 
 include_once CORE_TEST_CASES . DS . 'Http' . DS . 'server_mocks.php';
 
+use Cake\Http\Cookie\Cookie;
+use Cake\Http\Cookie\CookieCollection;
 use Cake\Http\Response;
 use Cake\Http\ServerRequest;
 use Cake\Network\Exception\NotFoundException;
@@ -1332,7 +1334,8 @@ class ResponseTest extends TestCase
             'path' => '/',
             'domain' => '',
             'secure' => false,
-            'httpOnly' => false];
+            'httpOnly' => false
+        ];
         $result = $response->cookie('CakeTestCookie[Testing]');
         $this->assertEquals($expected, $result);
 
@@ -1478,13 +1481,6 @@ class ResponseTest extends TestCase
     public function testGetCookies()
     {
         $response = new Response();
-        $cookie = [
-            'name' => 'ignored key',
-            'value' => '[a,b,c]',
-            'expire' => 1000,
-            'path' => '/test',
-            'secure' => true
-        ];
         $new = $response->withCookie('testing', 'a')
             ->withCookie('test2', ['value' => 'b', 'path' => '/test', 'secure' => true]);
         $expected = [
@@ -1511,6 +1507,28 @@ class ResponseTest extends TestCase
     }
 
     /**
+     * Test getCookieCollection() as array data
+     *
+     * @return void
+     */
+    public function testGetCookieCollection()
+    {
+        $response = new Response();
+        $new = $response->withCookie('testing', 'a')
+            ->withCookie('test2', ['value' => 'b', 'path' => '/test', 'secure' => true]);
+        $cookies = $response->getCookieCollection();
+        $this->assertInstanceOf(CookieCollection::class, $cookies);
+        $this->assertCount(0, $cookies, 'Original response not mutated');
+
+        $cookies = $new->getCookieCollection();
+        $this->assertInstanceOf(CookieCollection::class, $cookies);
+        $this->assertCount(2, $cookies);
+
+        $this->assertTrue($cookies->has('testing'));
+        $this->assertTrue($cookies->has('test2'));
+    }
+
+    /**
      * Test CORS
      *
      * @dataProvider corsData
@@ -3010,7 +3028,7 @@ class ResponseTest extends TestCase
             ],
             'file' => null,
             'fileRange' => [],
-            'cookies' => [],
+            'cookies' => new CookieCollection(),
             'cacheDirectives' => [],
             'body' => ''
         ];