Skip to content

Commit faa909c

Browse files
committed
Merge branch 'release/1.1.12' into v1
2 parents 9d566ac + 3635e18 commit faa909c

File tree

7 files changed

+98
-34
lines changed

7 files changed

+98
-34
lines changed

CHANGELOG.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
# Cookies Changelog
22

3-
## 1.1.11 - 2017.12.06
3+
## 1.1.12 - 2020.02.13
4+
### Changed
5+
* Implemented `sameSite` for cookies, thank to a PR from Kenny Quan
6+
7+
## 1.1.11 - 2018.12.06
48
### Changed
59
* Fixed an issue where `getSecure()` would return nothing due to an improper parameter passed to `unserialize()`
610

7-
## 1.1.10 - 2017.07.22
11+
## 1.1.10 - 2018.07.22
812
### Changed
913
* If the passed in domain is empty, use the `defaultCookieDomain` config setting
1014
* Don't unserialize any classes in secure cookie data
1115
* Code cleanup
1216

13-
## 1.1.9 - 2017.02.01
17+
## 1.1.9 - 2018.02.01
1418
### Changed
1519
* Renamed the composer package name to `craft-cookies`
1620
* Check to ensure a cookie exists before accessing it in `getSecure()`
1721

18-
## 1.1.8 - 2017.01.23
22+
## 1.1.8 - 2018.01.23
1923
### Changed
2024
* Fixed an issue with removing cookies
2125
* Added try/catch so errors are logged instead of exceptions thrown

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "nystudio107/craft-cookies",
33
"description": "A simple plugin for setting and getting cookies from within Craft CMS templates.",
44
"type": "craft-plugin",
5-
"version": "1.1.11",
5+
"version": "1.1.12",
66
"keywords": [
77
"craft",
88
"cms",

docs/docs/README.md

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,26 @@ You can also install Cookies via the **Plugin Store** in the Craft Control Panel
2222
## Setting cookies
2323

2424
All three of these methods accomplish the same thing:
25+
2526
```twig
2627
{# Set the cookie using 'setCookie' function #}
27-
{% do setCookie( NAME, VALUE, DURATION, PATH, DOMAIN, SECURE, HTTPONLY) %}
28+
{% do setCookie( NAME, VALUE, DURATION, PATH, DOMAIN, SECURE, HTTPONLY, SAMESITE) %}
2829
2930
{# Set the cookie using 'setCookie' filter #}
30-
{% do NAME | setCookie( VALUE, DURATION, PATH, DOMAIN, SECURE, HTTPONLY) %}
31+
{% do NAME | setCookie( VALUE, DURATION, PATH, DOMAIN, SECURE, HTTPONLY, SAMESITE) %}
3132
3233
{# Set the cookie using 'set' variable #}
33-
{% do craft.cookies.set( NAME, VALUE, DURATION, PATH, DOMAIN, SECURE, HTTPONLY) %}
34+
{% do craft.cookies.set( NAME, VALUE, DURATION, PATH, DOMAIN, SECURE, HTTPONLY, SAMESITE) %}
3435
```
36+
3537
They all act as a wrapper for the PHP `setcookie` function. [More info](http://php.net/manual/en/function.setcookie.php)
3638

37-
All of the parameters except for `NAME` are optional. The `PATH` defaults to `/` if not specified
39+
All of the parameters except for `NAME` are optional. The `PATH` defaults to `/` if not specified. The `SAMESITE` should be either 'None', 'Lax' or 'Strict'.
40+
41+
(Note: `SAMESITE` only works for environments with PHP 7.3 and up)
3842

3943
**Examples**
44+
4045
```twig
4146
{% do setCookie('marvin', 'martian', now | date_modify("+1 hour").timestamp) %}
4247
{# Sets a cookie to expire in an hour. #}
@@ -47,24 +52,30 @@ All of the parameters except for `NAME` are optional. The `PATH` defaults to `/
4752
{% do craft.cookies.set('marvin', 'martian', '', '/foo/' ) %}
4853
{# Cookie available within /foo/ directory and sub-directories. #}
4954
```
55+
5056
## Setting Secure cookies
5157

5258
All three of these methods accomplish the same thing:
59+
5360
```twig
5461
{# Set the cookie using 'setSecureCookie' function #}
55-
{% do setSecureCookie( NAME, VALUE, DURATION, PATH, DOMAIN, SECURE, HTTPONLY) %}
62+
{% do setSecureCookie( NAME, VALUE, DURATION, PATH, DOMAIN, SECURE, HTTPONLY, SAMESITE) %}
5663
5764
{# Set the cookie using 'setSecureCookie' filter #}
58-
{% do NAME | setSecureCookie( VALUE, DURATION, PATH, DOMAIN, SECURE, HTTPONLY) %}
65+
{% do NAME | setSecureCookie( VALUE, DURATION, PATH, DOMAIN, SECURE, HTTPONLY, SAMESITE) %}
5966
6067
{# Set the cookie using 'setSecure' variable #}
61-
{% do craft.cookies.setSecure( NAME, VALUE, DURATION, PATH, DOMAIN, SECURE, HTTPONLY) %}
68+
{% do craft.cookies.setSecure( NAME, VALUE, DURATION, PATH, DOMAIN, SECURE, HTTPONLY, SAMESITE) %}
6269
```
63-
This function works the same as `setCookie` but instead of using the PHP `setcookie` function, it uses the `Craft::$app->getResponse()->getCookies()->add` to add the cookies via Craft. It also utilizes `craft->security` framework to encrypt and validate the cookie contents between requests.
6470

65-
All of the parameters except for `NAME` are optional. The `PATH` defaults to `/` if not specified
71+
This function works the same as `setCookie` but instead of using the PHP `setcookie` function, it uses the `Craft::$app->getResponse()->getCookies()->add` to add the cookies via Craft. It also utilizes `craft->security` framework to encrypt and validate the cookie contents between requests.
72+
73+
All of the parameters except for `NAME` are optional. The `PATH` defaults to `/` if not specified. The `SAMESITE` should be either 'None', 'Lax' or 'Strict'.
74+
75+
(Note: `SAMESITE` only works for environments with PHP 7.3 and up)
6676

6777
**Examples**
78+
6879
```twig
6980
{% do setSecureCookie('marvin', 'martian', now | date_modify("+1 hour").timestamp) %}
7081
{# Sets a cookie to expire in an hour. #}
@@ -75,17 +86,21 @@ All of the parameters except for `NAME` are optional. The `PATH` defaults to `/
7586
{% do craft.cookies.setSecure('marvin', 'martian', '', '/foo/' ) %}
7687
{# Cookie available within /foo/ directory and sub-directories. #}
7788
```
89+
7890
## Retrieving cookies
7991

8092
Both of these methods accomplish the same thing:
93+
8194
```twig
8295
{# Get the cookie using 'getCookie' function #}
8396
{% do getCookie( NAME ) %}
8497
8598
{# Get the cookie using 'get' variable #}
8699
{% do craft.cookies.get( NAME ) %}
87100
```
101+
88102
**Example**
103+
89104
```twig
90105
{% do getCookie('marvin') %}
91106
{# Get the cookie using 'getCookie' function #}
@@ -98,17 +113,21 @@ Both of these methods accomplish the same thing:
98113
{{ myCookie }}
99114
{% endif %}
100115
```
116+
101117
## Retrieving Secure cookies
102118

103119
Both of these methods accomplish the same thing:
120+
104121
```twig
105122
{# Get the cookie using 'getSecureCookie' function #}
106123
{% do getSecureCookie( NAME ) %}
107124
108125
{# Get the cookie using 'getSecure' variable #}
109126
{% do craft.cookies.getSecure( NAME ) %}
110127
```
128+
111129
**Example**
130+
112131
```twig
113132
{% do getSecureCookie('marvin') %}
114133
{# Get the cookie using 'getSecureCookie' function #}
@@ -121,9 +140,11 @@ Both of these methods accomplish the same thing:
121140
{{ myCookie }}
122141
{% endif %}
123142
```
124-
This function works the same as `getCookie` but it uses `Craft::$app->getRequest()->getCookie()` to retrieve the cookies via Craft. It also utilizes `craft->security` framework to decrypt and validate the cookie contents between requests.
143+
144+
This function works the same as `getCookie` but it uses `Craft::$app->getRequest()->getCookie()` to retrieve the cookies via Craft. It also utilizes `craft->security` framework to decrypt and validate the cookie contents between requests.
125145

126146
**Example**
147+
127148
```twig
128149
{% do getSecureCookie('marvin') %}
129150
{# Get the cookie using 'getSecureCookie' function #}
@@ -136,9 +157,11 @@ This function works the same as `getCookie` but it uses `Craft::$app->getRequest
136157
{{ myCookie }}
137158
{% endif %}
138159
```
160+
139161
## Deleting cookies
140162

141163
All three of these methods accomplish the same thing:
164+
142165
```twig
143166
{# Delete a cookie by passing no VALUE to 'setCookie' function #}
144167
{% do setCookie( NAME ) %}
@@ -149,9 +172,11 @@ All three of these methods accomplish the same thing:
149172
{# Delete a cookie by passing no VALUE to 'set' variable #}
150173
{% do craft.cookies.set( NAME ) %}
151174
```
175+
152176
## Deleting Secure cookies
153177

154178
All three of these methods accomplish the same thing:
179+
155180
```twig
156181
{# Delete a cookie by passing no VALUE to 'setSecureCookie' function #}
157182
{% do setSecureCookie( NAME ) %}
@@ -162,4 +187,5 @@ All three of these methods accomplish the same thing:
162187
{# Delete a cookie by passing no VALUE to 'setSecure' variable #}
163188
{% do craft.cookies.setSecure( NAME ) %}
164189
```
190+
165191
Brought to you by [nystudio107](http://nystudio107.com)

src/Cookies.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
/**
34
* Cookies plugin for Craft CMS 3.x
45
*

src/services/CookiesService.php

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
/**
34
* Cookies plugin for Craft CMS 3.x
45
*
@@ -36,6 +37,7 @@ class CookiesService extends Component
3637
* @param string $domain
3738
* @param bool $secure
3839
* @param bool $httpOnly
40+
* @param string $sameSite
3941
*/
4042
public function set(
4143
$name = '',
@@ -44,14 +46,26 @@ public function set(
4446
$path = '/',
4547
$domain = '',
4648
$secure = false,
47-
$httpOnly = false
49+
$httpOnly = false,
50+
$sameSite = null
4851
) {
4952
if (empty($value)) {
5053
Craft::$app->response->cookies->remove($name);
5154
} else {
5255
$domain = empty($domain) ? Craft::$app->getConfig()->getGeneral()->defaultCookieDomain : $domain;
53-
$expire = (int)$expire;
54-
setcookie($name, $value, $expire, $path, $domain, $secure, $httpOnly);
56+
$expire = (int) $expire;
57+
if (PHP_VERSION_ID >= 70300) {
58+
setcookie($name, $value, [
59+
'expires' => $expire,
60+
'path' => $path,
61+
'domain' => $domain,
62+
'secure' => true,
63+
'httponly' => $httpOnly,
64+
'samesite' => $sameSite
65+
]);
66+
} else {
67+
setcookie($name, $value, $expire, $path, $domain, $secure, $httpOnly);
68+
}
5569
$_COOKIE[$name] = $value;
5670
}
5771
}
@@ -83,6 +97,7 @@ public function get($name = '')
8397
* @param string $domain
8498
* @param bool $secure
8599
* @param bool $httpOnly
100+
* @param string $sameSite
86101
*/
87102
public function setSecure(
88103
$name = '',
@@ -91,27 +106,28 @@ public function setSecure(
91106
$path = '/',
92107
$domain = '',
93108
$secure = false,
94-
$httpOnly = false
109+
$httpOnly = false,
110+
$sameSite = null
95111
) {
96112
if (empty($value)) {
97113
Craft::$app->response->cookies->remove($name);
98114
} else {
99115
$domain = empty($domain) ? Craft::$app->getConfig()->getGeneral()->defaultCookieDomain : $domain;
100-
$expire = (int)$expire;
116+
$expire = (int) $expire;
101117
$cookie = new Cookie(['name' => $name, 'value' => '']);
102118

103119
try {
104120
$cookie->value = Craft::$app->security->hashData(base64_encode(serialize($value)));
105121
} catch (InvalidConfigException $e) {
106122
Craft::error(
107-
'Error setting secure cookie: '.$e->getMessage(),
123+
'Error setting secure cookie: ' . $e->getMessage(),
108124
__METHOD__
109125
);
110126

111127
return;
112128
} catch (Exception $e) {
113129
Craft::error(
114-
'Error setting secure cookie: '.$e->getMessage(),
130+
'Error setting secure cookie: ' . $e->getMessage(),
115131
__METHOD__
116132
);
117133

@@ -122,7 +138,9 @@ public function setSecure(
122138
$cookie->domain = $domain;
123139
$cookie->secure = $secure;
124140
$cookie->httpOnly = $httpOnly;
125-
141+
if (PHP_VERSION_ID >= 70300) {
142+
$cookie->sameSite = $sameSite;
143+
}
126144
Craft::$app->response->cookies->add($cookie);
127145
}
128146
}
@@ -143,18 +161,19 @@ public function getSecure($name = '')
143161
$data = Craft::$app->security->validateData($cookie->value);
144162
} catch (InvalidConfigException $e) {
145163
Craft::error(
146-
'Error getting secure cookie: '.$e->getMessage(),
164+
'Error getting secure cookie: ' . $e->getMessage(),
147165
__METHOD__
148166
);
149167
$data = false;
150168
} catch (Exception $e) {
151169
Craft::error(
152-
'Error getting secure cookie: '.$e->getMessage(),
170+
'Error getting secure cookie: ' . $e->getMessage(),
153171
__METHOD__
154172
);
155173
$data = false;
156174
}
157-
if ($cookie
175+
if (
176+
$cookie
158177
&& !empty($cookie->value)
159178
&& $data !== false
160179
) {

src/twigextensions/CookiesTwigExtension.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
/**
34
* Cookies plugin for Craft CMS 3.x
45
*
@@ -69,6 +70,7 @@ public function getFunctions()
6970
* @param string $domain
7071
* @param bool $secure
7172
* @param bool $httpOnly
73+
* @param string $sameSite
7274
*/
7375
public function setCookie(
7476
$name = "",
@@ -77,7 +79,8 @@ public function setCookie(
7779
$path = "/",
7880
$domain = "",
7981
$secure = false,
80-
$httpOnly = false
82+
$httpOnly = false,
83+
$sameSite = null
8184
) {
8285
Cookies::$plugin->cookies->set(
8386
$name,
@@ -86,7 +89,8 @@ public function setCookie(
8689
$path,
8790
$domain,
8891
$secure,
89-
$httpOnly
92+
$httpOnly,
93+
$sameSite
9094
);
9195
}
9296

@@ -112,6 +116,7 @@ public function getCookie($name)
112116
* @param string $domain
113117
* @param bool $secure
114118
* @param bool $httpOnly
119+
* @param string $sameSite
115120
*/
116121
public function setSecureCookie(
117122
$name = "",
@@ -120,7 +125,8 @@ public function setSecureCookie(
120125
$path = "/",
121126
$domain = "",
122127
$secure = false,
123-
$httpOnly = false
128+
$httpOnly = false,
129+
$sameSite = null
124130
) {
125131
Cookies::$plugin->cookies->setSecure(
126132
$name,
@@ -129,7 +135,8 @@ public function setSecureCookie(
129135
$path,
130136
$domain,
131137
$secure,
132-
$httpOnly
138+
$httpOnly,
139+
$sameSite
133140
);
134141
}
135142

0 commit comments

Comments
 (0)