@@ -90,16 +90,17 @@ public static function create(string $name, string $value = null, $expire = 0, ?
90
90
*/
91
91
public function __construct (string $ name , string $ value = null , $ expire = 0 , ?string $ path = '/ ' , string $ domain = null , bool $ secure = null , bool $ httpOnly = true , bool $ raw = false , ?string $ sameSite = 'lax ' )
92
92
{
93
- $ this
94
- ->setRaw ($ raw )
95
- ->setName ($ name )
96
- ->setValue ($ value )
97
- ->setExpiresTime ($ expire )
98
- ->setPath ($ path )
99
- ->setDomain ($ domain )
100
- ->setSecure ($ secure )
101
- ->setHttpOnly ($ httpOnly )
102
- ->setSameSite ($ sameSite );
93
+ $ this ->raw = $ raw ;
94
+
95
+ $ this ->validateName ($ name );
96
+ $ this ->name = $ name ;
97
+ $ this ->value = $ value ;
98
+ $ this ->expire = $ this ->normalizeExpiresTime ($ expire );
99
+ $ this ->path = $ this ->normalizePath ($ path );
100
+ $ this ->domain = $ domain ;
101
+ $ this ->secure = $ secure ;
102
+ $ this ->httpOnly = $ httpOnly ;
103
+ $ this ->sameSite = $ this ->normalizeSameSite ($ sameSite );
103
104
}
104
105
105
106
/**
@@ -161,13 +162,21 @@ public function getName()
161
162
}
162
163
163
164
/**
164
- * Sets the name of the cookie.
165
- *
166
- * @return $this
165
+ * Creates a cookie copy with a new name.
167
166
*
168
167
* @throws \InvalidArgumentException
169
168
*/
170
- public function setName (string $ name ): self
169
+ public function withName (string $ name ): self
170
+ {
171
+ $ this ->validateName ($ name );
172
+
173
+ $ cookie = clone $ this ;
174
+ $ cookie ->name = $ name ;
175
+
176
+ return $ cookie ;
177
+ }
178
+
179
+ private function validateName (string $ name ): void
171
180
{
172
181
// from PHP source code
173
182
if ($ this ->isRaw () && false !== strpbrk ($ name , self ::$ reservedCharsList )) {
@@ -177,10 +186,6 @@ public function setName(string $name): self
177
186
if (empty ($ name )) {
178
187
throw new \InvalidArgumentException ('The cookie name cannot be empty. ' );
179
188
}
180
-
181
- $ this ->name = $ name ;
182
-
183
- return $ this ;
184
189
}
185
190
186
191
/**
@@ -194,15 +199,14 @@ public function getValue()
194
199
}
195
200
196
201
/**
197
- * Sets the cookie value.
198
- *
199
- * @return $this
202
+ * Creates a cookie copy with a new value.
200
203
*/
201
- public function setValue (string $ value = null ): self
204
+ public function withValue (string $ value = null ): self
202
205
{
203
- $ this ->value = $ value ;
206
+ $ cookie = clone $ this ;
207
+ $ cookie ->value = $ value ;
204
208
205
- return $ this ;
209
+ return $ cookie ;
206
210
}
207
211
208
212
/**
@@ -216,15 +220,14 @@ public function getDomain()
216
220
}
217
221
218
222
/**
219
- * Sets the domain that the cookie is available to.
220
- *
221
- * @return $this
223
+ * Creates a cookie copy with a new domain that the cookie is available to.
222
224
*/
223
- public function setDomain (string $ domain = null ): self
225
+ public function withDomain (string $ domain = null ): self
224
226
{
225
- $ this ->domain = $ domain ;
227
+ $ cookie = clone $ this ;
228
+ $ cookie ->domain = $ domain ;
226
229
227
- return $ this ;
230
+ return $ cookie ;
228
231
}
229
232
230
233
/**
@@ -238,15 +241,23 @@ public function getExpiresTime()
238
241
}
239
242
240
243
/**
241
- * Sets the time the cookie expires.
244
+ * Creates a cookie copy with a new time the cookie expires.
242
245
*
243
246
* @param int|string|\DateTimeInterface $expire
244
247
*
245
- * @return $this
246
- *
247
248
* @throws \InvalidArgumentException
248
249
*/
249
- public function setExpiresTime ($ expire = 0 ): self
250
+ public function withExpiresTime ($ expire = 0 ): self
251
+ {
252
+ $ expire = $ this ->normalizeExpiresTime ($ expire );
253
+
254
+ $ cookie = clone $ this ;
255
+ $ cookie ->expire = $ expire ;
256
+
257
+ return $ cookie ;
258
+ }
259
+
260
+ private function normalizeExpiresTime ($ expire = 0 ): int
250
261
{
251
262
// convert expiration time to a Unix timestamp
252
263
if ($ expire instanceof \DateTimeInterface) {
@@ -259,9 +270,7 @@ public function setExpiresTime($expire = 0): self
259
270
}
260
271
}
261
272
262
- $ this ->expire = 0 < $ expire ? (int ) $ expire : 0 ;
263
-
264
- return $ this ;
273
+ return 0 < $ expire ? (int ) $ expire : 0 ;
265
274
}
266
275
267
276
/**
@@ -287,15 +296,19 @@ public function getPath()
287
296
}
288
297
289
298
/**
290
- * Sets the path on the server in which the cookie will be available on.
291
- *
292
- * @return $this
299
+ * Creates a cookie copy with a new path on the server in which the cookie will be available on.
293
300
*/
294
- public function setPath (?string $ path ): self
301
+ public function withPath (?string $ path ): self
295
302
{
296
- $ this ->path = empty ($ path ) ? '/ ' : $ path ;
303
+ $ cookie = clone $ this ;
304
+ $ cookie ->path = $ this ->normalizePath ($ path );
297
305
298
- return $ this ;
306
+ return $ cookie ;
307
+ }
308
+
309
+ private function normalizePath (?string $ path ): string
310
+ {
311
+ return empty ($ path ) ? '/ ' : $ path ;
299
312
}
300
313
301
314
/**
@@ -309,15 +322,14 @@ public function isSecure()
309
322
}
310
323
311
324
/**
312
- * Makes cookie only be transmitted over a secure HTTPS connection from the client.
313
- *
314
- * @return $this
325
+ * Creates a cookie copy that only be transmitted over a secure HTTPS connection from the client.
315
326
*/
316
- public function setSecure (bool $ secure = null ): self
327
+ public function withSecure (bool $ secure = null ): self
317
328
{
318
- $ this ->secure = $ secure ;
329
+ $ cookie = clone $ this ;
330
+ $ cookie ->secure = $ secure ;
319
331
320
- return $ this ;
332
+ return $ cookie ;
321
333
}
322
334
323
335
/**
@@ -331,15 +343,14 @@ public function isHttpOnly()
331
343
}
332
344
333
345
/**
334
- * Makes cookie accessible only through the HTTP protocol.
335
- *
336
- * @return $this
346
+ * Creates a cookie copy that be accessible only through the HTTP protocol.
337
347
*/
338
- public function setHttpOnly (bool $ httpOnly = true ): self
348
+ public function withHttpOnly (bool $ httpOnly = true ): self
339
349
{
340
- $ this ->httpOnly = $ httpOnly ;
350
+ $ cookie = clone $ this ;
351
+ $ cookie ->httpOnly = $ httpOnly ;
341
352
342
- return $ this ;
353
+ return $ cookie ;
343
354
}
344
355
345
356
/**
@@ -363,15 +374,14 @@ public function isRaw()
363
374
}
364
375
365
376
/**
366
- * Toggles cookie value url encoding.
367
- *
368
- * @return $this
377
+ * Creates a cookie copy that uses url encoding.
369
378
*/
370
- public function setRaw (bool $ raw = false ): self
379
+ public function withRaw (bool $ raw = false ): self
371
380
{
372
- $ this ->raw = $ raw ;
381
+ $ cookie = clone $ this ;
382
+ $ cookie ->raw = $ raw ;
373
383
374
- return $ this ;
384
+ return $ cookie ;
375
385
}
376
386
377
387
/**
@@ -385,13 +395,21 @@ public function getSameSite()
385
395
}
386
396
387
397
/**
388
- * Sets the SameSite attribute.
389
- *
390
- * @return $this
398
+ * Creates a cookie copy with SameSite attribute.
391
399
*
392
400
* @throws \InvalidArgumentException
393
401
*/
394
- public function setSameSite (?string $ sameSite = 'lax ' ): self
402
+ public function withSameSite (?string $ sameSite = 'lax ' ): self
403
+ {
404
+ $ sameSite = $ this ->normalizeSameSite ($ sameSite );
405
+
406
+ $ cookie = clone $ this ;
407
+ $ cookie ->sameSite = $ sameSite ;
408
+
409
+ return $ cookie ;
410
+ }
411
+
412
+ private function normalizeSameSite (?string $ sameSite = 'lax ' ): ?string
395
413
{
396
414
if ('' === $ sameSite ) {
397
415
$ sameSite = null ;
@@ -403,9 +421,7 @@ public function setSameSite(?string $sameSite = 'lax'): self
403
421
throw new \InvalidArgumentException ('The "sameSite" parameter value is not valid. ' );
404
422
}
405
423
406
- $ this ->sameSite = $ sameSite ;
407
-
408
- return $ this ;
424
+ return $ sameSite ;
409
425
}
410
426
411
427
/**
0 commit comments