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