Browse Source

Merge pull request #10981 from jorisvaesen/3.next

Response withExpiredCookie
Mark Story 8 years ago
parent
commit
5d9c6d7155

+ 1 - 1
src/Http/Cookie/Cookie.php

@@ -510,7 +510,7 @@ class Cookie implements CookieInterface
     public function withExpired()
     {
         $new = clone $this;
-        $new->expiresAt = Chronos::parse('-1 year');
+        $new->expiresAt = Chronos::createFromTimestamp(1);
 
         return $new;
     }

+ 57 - 0
src/Http/Response.php

@@ -2041,6 +2041,63 @@ class Response implements ResponseInterface
     }
 
     /**
+     * Create a new response with an expired cookie set.
+     *
+     * ### Options
+     *
+     * - `name`: The Cookie name
+     * - `path`: Path the cookie applies to
+     * - `domain`: Domain the cookie is for.
+     * - `secure`: Is the cookie https?
+     * - `httpOnly`: Is the cookie available in the client?
+     *
+     * ### Examples
+     *
+     * ```
+     * // set scalar value with defaults
+     * $response = $response->withExpiredCookie('remember_me');
+     *
+     * // customize cookie attributes
+     * $response = $response->withExpiredCookie('remember_me', ['path' => '/login']);
+     *
+     * // add a cookie object
+     * $response = $response->withExpiredCookie(new Cookie('remember_me'));
+     * ```
+     *
+     * @param string|\Cake\Http\Cookie\CookieInterface $name The name of the cookie to expire, or a cookie object
+     * @param array $options An array of cookie options.
+     * @return static
+     */
+    public function withExpiredCookie($name, $options = [])
+    {
+        if ($name instanceof CookieInterface) {
+            $cookie = $name->withExpired();
+        } else {
+            $options += [
+                'path' => '/',
+                'domain' => '',
+                'secure' => false,
+                'httpOnly' => false
+            ];
+
+            $cookie = new Cookie(
+                $name,
+                '',
+                DateTime::createFromFormat('U', 1),
+                $options['path'],
+                $options['domain'],
+                $options['secure'],
+                $options['httpOnly']
+            );
+        }
+
+        $new = clone $this;
+        $new->_cookies = $new->_cookies->add($cookie);
+
+        return $new;
+    }
+
+    /**
      * Read a single cookie from the response.
      *
      * This method provides read access to pending cookies. It will

+ 1 - 2
tests/TestCase/Http/Cookie/CookieTest.php

@@ -298,8 +298,7 @@ class CookieTest extends TestCase
         $this->assertNotSame($new, $cookie, 'Should clone');
         $this->assertNotContains('expiry', $cookie->toHeaderValue());
 
-        $now = Chronos::parse('-1 year');
-        $this->assertContains($now->format('Y'), $new->toHeaderValue());
+        $this->assertContains('01-Jan-1970', $new->toHeaderValue());
     }
 
     /**

+ 48 - 0
tests/TestCase/Http/ResponseTest.php

@@ -1491,6 +1491,54 @@ class ResponseTest extends TestCase
         $this->assertSame($cookie, $new->getCookieCollection()->get('yay'));
     }
 
+    public function testWithExpiredCookieScalar()
+    {
+        $response = new Response();
+        $response = $response->withCookie('testing', 'abc123');
+        $this->assertEquals('abc123', $response->getCookie('testing')['value']);
+
+        $new = $response->withExpiredCookie('testing');
+
+        $this->assertNull($response->getCookie('testing')['expire']);
+        $this->assertEquals('1', $new->getCookie('testing')['expire']);
+    }
+
+    public function testWithExpiredCookieOptions()
+    {
+        $options = [
+            'name' => 'testing',
+            'value' => 'abc123',
+            'domain' => 'cakephp.org',
+            'path' => '/custompath/',
+            'secure' => true,
+            'httpOnly' => true,
+            'expire' => (string)strtotime('+14 days'),
+        ];
+
+        $response = new Response();
+        $response = $response->withCookie('testing', $options);
+        $this->assertEquals($options, $response->getCookie('testing'));
+
+        $new = $response->withExpiredCookie('testing', $options);
+
+        $this->assertEquals($options['expire'], $response->getCookie('testing')['expire']);
+        $this->assertEquals('1', $new->getCookie('testing')['expire']);
+        $this->assertEquals('', $new->getCookie('testing')['value']);
+    }
+
+    public function testWithExpiredCookieObject()
+    {
+        $response = new Response();
+        $cookie = new Cookie('yay', 'a value');
+        $response = $response->withCookie($cookie);
+        $this->assertEquals('a value', $response->getCookie('yay')['value']);
+
+        $new = $response->withExpiredCookie($cookie);
+
+        $this->assertNull($response->getCookie('yay')['expire']);
+        $this->assertEquals('1', $new->getCookie('yay')['expire']);
+    }
+
     /**
      * Test getCookies() and array data.
      *