1: <?php
2:
3: declare(strict_types=1);
4:
5: /**
6: * This file is part of the Nexus framework.
7: *
8: * (c) John Paul E. Balandan, CPA <paulbalandan@gmail.com>
9: *
10: * For the full copyright and license information, please view
11: * the LICENSE file that was distributed with this source code.
12: */
13:
14: namespace Nexus\Cookie;
15:
16: /**
17: * Interface for an immutable cookie object.
18: */
19: interface CookieInterface extends \Stringable
20: {
21: /**
22: * RFC 7231 compliant date format for cookie expiration.
23: */
24: public const EXPIRES_FORMAT = 'D, d M Y H:i:s T';
25:
26: /**
27: * Cookies will be sent in all contexts, i.e in responses to both
28: * first-party and cross-origin requests. If `SameSite=None` is set,
29: * the cookie `Secure` attribute must also be set (or the cookie will be blocked).
30: */
31: public const SAMESITE_NONE = 'None';
32:
33: /**
34: * Cookies are not sent on normal cross-site subrequests (for example to
35: * load images or frames into a third party site), but are sent when a
36: * user is navigating to the origin site (i.e. when following a link).
37: */
38: public const SAMESITE_LAX = 'Lax';
39:
40: /**
41: * Cookies will only be sent in a first-party context and not be sent
42: * along with requests initiated by third party websites.
43: */
44: public const SAMESITE_STRICT = 'Strict';
45:
46: /**
47: * Converts a `Set-Cookie` header string to a `CookieInterface` object.
48: *
49: * @param non-empty-string $header The `Set-Cookie` header string
50: * @param bool $raw Whether the cookie value should be sent without URL encoding
51: *
52: * @throws \InvalidArgumentException
53: */
54: public static function fromHeader(string $header, bool $raw = false): self;
55:
56: /**
57: * Gets the prefix of the cookie.
58: */
59: public function getPrefix(): string;
60:
61: /**
62: * Gets the name of the cookie without the prefix.
63: *
64: * @return non-empty-string
65: */
66: public function getName(): string;
67:
68: /**
69: * Gets the name of the cookie with the prefix.
70: *
71: * @return non-empty-string
72: */
73: public function getPrefixedName(): string;
74:
75: /**
76: * Gets the value of the cookie.
77: */
78: public function getValue(): string;
79:
80: /**
81: * Gets the path on the server in which the cookie will be available on.
82: */
83: public function getPath(): string;
84:
85: /**
86: * Gets the (sub)domain that the cookie is available to.
87: */
88: public function getDomain(): string;
89:
90: /**
91: * Gets the `Max-Age` attribute of the cookie.
92: *
93: * @return int<0, max>
94: */
95: public function getMaxAge(): int;
96:
97: /**
98: * Gets the time when the cookie expires.
99: *
100: * @return int<0, max>
101: */
102: public function getExpiresTimestamp(): int;
103:
104: /**
105: * Indicates if the cookie has expired.
106: */
107: public function isExpired(): bool;
108:
109: /**
110: * Indicates if the cookie should only be transmitted over a secure HTTPS connection from the client.
111: */
112: public function isSecure(): bool;
113:
114: /**
115: * Indicates if the cookie will be accessible only through the HTTP protocol.
116: */
117: public function isHttpOnly(): bool;
118:
119: /**
120: * Gets the `SameSite` attribute of the cookie.
121: *
122: * @return self::SAMESITE_*
123: */
124: public function getSameSite(): string;
125:
126: /**
127: * Gets the cookie options that are passable to the `setcookie()` function.
128: *
129: * @return array{
130: * expires: int<0, max>,
131: * path: string,
132: * domain: string,
133: * secure: bool,
134: * httponly: bool,
135: * samesite: string,
136: * }
137: */
138: public function getOptions(): array;
139:
140: /**
141: * Indicates if the cookie value should be sent without URL encoding.
142: */
143: public function isRaw(): bool;
144:
145: /**
146: * Indicates if the cookie should be tied to the top-level site in a cross-site context.
147: *
148: * @see https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Privacy_sandbox/Partitioned_cookies
149: */
150: public function isPartitioned(): bool;
151:
152: /**
153: * Creates a cookie object with the new prefix.
154: */
155: public function withPrefix(string $prefix): self;
156:
157: /**
158: * Creates a cookie object with the new name.
159: */
160: public function withName(string $name): self;
161:
162: /**
163: * Creates a cookie object with the new value.
164: */
165: public function withValue(string $value): self;
166:
167: /**
168: * Creates a cookie object with the new `Path` attribute.
169: */
170: public function withPath(string $path): self;
171:
172: /**
173: * Creates a cookie object with the new `Domain` attribute.
174: */
175: public function withDomain(string $domain): self;
176:
177: /**
178: * Creates a cookie object with the new `Max-Age` attribute.
179: */
180: public function withMaxAge(int $maxAge): self;
181:
182: /**
183: * Creates a cookie object with the new `Expires` attribute.
184: *
185: * @param \DateTimeInterface|int<0, max>|string $expires
186: */
187: public function withExpiresTime(\DateTimeInterface|int|string $expires): self;
188:
189: /**
190: * Creates a cookie object with the new `Secure` attribute.
191: */
192: public function withSecure(bool $secure): self;
193:
194: /**
195: * Creates a cookie object with the new `HttpOnly` attribute.
196: */
197: public function withHttpOnly(bool $httpOnly): self;
198:
199: /**
200: * Creates a cookie object with the new `SameSite` attribute.
201: */
202: public function withSameSite(?string $sameSite): self;
203:
204: /**
205: * Creates a cookie object that whether the cookie value should be sent without URL encoding.
206: */
207: public function withRaw(bool $raw): self;
208:
209: /**
210: * Creates a cookie object that whether the cookie should be tied to the top-level site in a cross-site context.
211: *
212: * @see https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Privacy_sandbox/Partitioned_cookies
213: */
214: public function withPartitioned(bool $partitioned): self;
215: }
216: