PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 2.4.0
Fluent Support – Helpdesk & Customer Support Ticket System v2.4.0
2.4.0 2.3.2 2.3.1 2.3.0 2.2.1 2.2.0 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.4.0 1.4.1 1.4.2 1.4.5 1.4.6 1.4.7 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 All 68 releases
fluent-support / vendor / wpfluent / framework / src / WPFluent / Http / URL.php

URL.php in Fluent Support – Helpdesk & Customer Support Ticket System 2.4.0, at vendor/wpfluent/framework/src/WPFluent/Http/URL.php

512 lines 8.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentSupport\Framework\Http;
4
5 use Exception;
6 use InvalidArgumentException;
7 use FluentSupport\Framework\Support\Util;
8 use FluentSupport\Framework\Foundation\App;
9 use FluentSupport\Framework\Support\UriTemplate;
10
11 class URL
12 {
13 /**
14 * The full URL string.
15 *
16 * @var string
17 */
18 protected $url = '';
19
20 /**
21 * URL generator instance used for signing and route generation.
22 *
23 * @var UrlGenerator|null
24 */
25 protected $generator = null;
26
27 /**
28 * URL scheme (e.g., 'http', 'https').
29 *
30 * @var string
31 */
32 protected $scheme = '';
33
34 /**
35 * URL host (e.g., 'example.com').
36 *
37 * @var string|null
38 */
39 protected $host = null;
40
41 /**
42 * URL port (e.g., 80, 443).
43 *
44 * @var int|null
45 */
46 protected $port = null;
47
48 /**
49 * URL path (e.g., '/users/view').
50 *
51 * @var string
52 */
53 protected $path = '';
54
55 /**
56 * URL query parameters as an associative array.
57 *
58 * @var array
59 */
60 protected $query = [];
61
62 /**
63 * URL fragment (e.g., 'top' in '#top').
64 *
65 * @var string|null
66 */
67 protected $fragment = null;
68
69 /**
70 * URL username for authentication (if any).
71 *
72 * @var string|null
73 */
74 protected $user = null;
75
76 /**
77 * URL password for authentication (if any).
78 *
79 * @var string|null
80 */
81 protected $pass = null;
82
83 /**
84 * Constructor.
85 *
86 * @param string|null $url Optional URL to initialize. Defaults to current URL.
87 * @param UrlGenerator|null $generator Optional generator instance for signing/routes.
88 *
89 * @throws InvalidArgumentException If the given URL is invalid.
90 */
91 public function __construct($url = '', $generator = null)
92 {
93 $this->prepareRfcProperties(
94 $this->url = $url ?: $this->current()
95 );
96
97 $this->generator = $generator ?: new UrlGenerator();
98 }
99
100 /**
101 * Parse a URL according to RFC 3986 and populate internal components.
102 *
103 * @param string $url The URL to parse.
104 *
105 * @return void
106 *
107 * @throws InvalidArgumentException If the URL cannot be parsed.
108 */
109 protected function prepareRfcProperties($url)
110 {
111 // --- Parse URL according to RFC3986 ---
112 $parts = parse_url($url);
113
114 if ($parts === false) {
115 throw new InvalidArgumentException("Invalid URL: {$url}");
116 }
117
118 $this->scheme = $parts['scheme'] ?? '';
119 $this->host = $parts['host'] ?? null;
120 $this->port = $parts['port'] ?? null;
121 $this->path = $parts['path'] ?? null;
122 $this->user = $parts['user'] ?? null;
123 $this->pass = $parts['pass'] ?? null;
124 $this->fragment = $parts['fragment'] ?? null;
125
126 if (isset($parts['query'])) {
127 parse_str($parts['query'], $query);
128 $this->query = $query;
129 } else {
130 $this->query = [];
131 }
132 }
133
134 /**
135 * Create a new URL instance.
136 *
137 * @param string $uri
138 * @return static
139 */
140 public static function of($uri)
141 {
142 $parts = parse_url($uri);
143
144 if ($parts === false) {
145 throw new InvalidArgumentException("Invalid URI: {$uri}");
146 }
147
148 return new static($uri);
149 }
150
151 /**
152 * Get the current URL
153 *
154 * @return string
155 */
156 public function current()
157 {
158 return rtrim(get_site_url(), '/') . $_SERVER['REQUEST_URI'];
159 }
160
161 /**
162 * Parse a url from uncompiled route
163 *
164 * @param string $url
165 * @param array $params
166 * @return string
167 */
168 public function parse(string $url, array $params)
169 {
170 return UriTemplate::expand($url, $params);
171 }
172
173 /**
174 * Sign the current url.
175 *
176 * @param array $params
177 * @return string
178 */
179 public function signCurrentUrl($params = [])
180 {
181 return $this->sign($this->current(), $params);
182 }
183
184 /**
185 * Sign a URL
186 *
187 * @param string $url
188 * @param array $params
189 * @return string
190 */
191 public function sign($url, $params = [])
192 {
193 return $this->generator->sign($url, $params);
194 }
195
196 /**
197 * Validate a URL
198 *
199 * @param string $url
200 * @return mixed (false or array)
201 */
202 public function validate($url)
203 {
204 return $this->generator->validate($url);
205 }
206
207 /**
208 * Helper method for home_url.
209 *
210 * @return string
211 */
212 public function wp($path = '')
213 {
214 $wp = get_option('siteUrl');
215
216 if ($path) {
217 $wp .= '/' . trim($path, '/');
218 }
219
220 return $wp;
221 }
222
223 /**
224 * Retrieve the wp-content URL.
225 *
226 * Note: The wp-content directory is renamable by devs so it's not
227 * guaranteed to be wp-content, so use this method for safety.
228 *
229 * @param string $path
230 * @return string
231 */
232 public function content($path = '')
233 {
234 return content_url($path);
235 }
236
237 /**
238 * Retrieve the wp-content/plugins URL.
239 *
240 * @param string $path
241 * @return string
242 */
243 public function plugins($path = '')
244 {
245 return $this->content('/plugins/' . ltrim($path, '/'));
246 }
247
248 /**
249 * Retrieve the wp-content/plugins URL.
250 *
251 * @param string $path
252 * @return string
253 */
254 public function plugin($path = '')
255 {
256 $pluginUrl = rtrim(plugin_dir_url(
257 App::make('__pluginfile__')
258 ), '/');
259
260 if ($path) {
261 $pluginUrl .= '/' . trim($path, '/');
262 }
263
264 return $pluginUrl;
265 }
266
267 /**
268 * Retrieve the wp-content/themes URL.
269 *
270 * @param string $path
271 * @return string
272 */
273 public function themes($path = '')
274 {
275 return $this->content('/themes/' . ltrim($path, '/'));
276 }
277
278 /**
279 * Retrieve the wp-content/uploads URL.
280 *
281 * @param string $path
282 * @return string
283 */
284 public function uploads($path = '')
285 {
286 return $this->content('/uploads/' . ltrim($path, '/'));
287 }
288
289 /**
290 * Retrieve the site/home URL.
291 *
292 * @param string $path
293 * @return string
294 */
295 public function home($path = '', $scheme = null)
296 {
297 return site_url($path, $scheme);
298 }
299
300 /**
301 * Generate a URL from a file path.
302 *
303 * @param string $path
304 * @param bool $checkFile Whether to check if the file exists
305 * @return string
306 *
307 * @phpstan-ignore-next-line
308 */
309 public function fromFile(string $path, bool $checkFile = false): string
310 {
311 return Util::pathToUrl($path, $checkFile);
312 }
313
314 /**
315 * Generate a URL from a named route.
316 *
317 * @param string $name
318 * @param array $params
319 * @param array $query
320 * @return string|null
321 */
322 public function route($name, $params = [], $query = [])
323 {
324 return $this->generator->route($name, $params, $query);
325 }
326
327 /**
328 * Return a clone of the URL with a new path.
329 *
330 * @param string $path
331 * @return $this
332 */
333 public function withPath($path)
334 {
335 $clone = clone $this;
336 $clone->path = $path;
337 return $clone;
338 }
339
340 /**
341 * Return a clone of the URL with a new query.
342 *
343 * @param array|string $query An array of query params or a query string
344 * @return $this
345 */
346 public function withQuery($query)
347 {
348 $clone = clone $this;
349
350 if (is_string($query)) {
351 parse_str($query, $query);
352 }
353
354 $clone->query = $query;
355 return $clone;
356 }
357
358 /**
359 * Return a clone of the URL with a new fragment.
360 *
361 * @param string $fragment
362 * @return $this
363 */
364 public function withFragment($fragment)
365 {
366 $clone = clone $this;
367 $clone->fragment = $fragment;
368 return $clone;
369 }
370
371 /**
372 * Return a clone of the URL with a new scheme.
373 *
374 * @param string $scheme
375 * @return $this
376 */
377 public function withScheme($scheme)
378 {
379 $clone = clone $this;
380 $clone->scheme = $scheme;
381 return $clone;
382 }
383
384 /**
385 * Get the URL scheme (e.g., 'http' or 'https').
386 *
387 * @return string
388 */
389 public function scheme()
390 {
391 return $this->scheme;
392 }
393
394 /**
395 * Get the URL host.
396 *
397 * @return string|null
398 */
399 public function host()
400 {
401 return $this->host;
402 }
403
404 /**
405 * Get the URL port.
406 *
407 * @return int|null
408 */
409 public function port()
410 {
411 return $this->port;
412 }
413
414 /**
415 * Get the URL path.
416 *
417 * @return string
418 */
419 public function path()
420 {
421 return $this->path;
422 }
423
424 /**
425 * Get the URL query as an array.
426 *
427 * @return array
428 */
429 public function query()
430 {
431 return $this->query;
432 }
433
434 /**
435 * Get the URL fragment.
436 *
437 * @return string|null
438 */
439 public function fragment()
440 {
441 return $this->fragment;
442 }
443
444 /**
445 * Get the URL pass.
446 *
447 * @return string|null
448 */
449 public function pass()
450 {
451 return $this->pass;
452 }
453
454 /**
455 * Get the URL user.
456 *
457 * @return string
458 */
459 public function user()
460 {
461 return $this->user;
462 }
463
464 /**
465 * Returns the string representation of the URL object.
466 *
467 * @return string Current URL.
468 */
469 public function __toString()
470 {
471 $url = '';
472
473 if ($this->scheme) {
474 $url .= "{$this->scheme}://";
475 }
476
477 if ($this->user) {
478 $url .= $this->user;
479 if ($this->pass) {
480 $url .= ":{$this->pass}";
481 }
482 $url .= '@';
483 }
484
485 if ($this->host) {
486 $url .= $this->host;
487 }
488
489 if ($this->port) {
490 $url .= ":{$this->port}";
491 }
492
493 if ($this->path !== null) {
494 $url .= $this->path === '' || str_starts_with($this->path, '/')
495 ? $this->path
496 : '/' . $this->path;
497 }
498
499 if (!empty($this->query)) {
500 $url .= '?' . http_build_query(
501 $this->query, '', '&', PHP_QUERY_RFC3986
502 );
503 }
504
505 if ($this->fragment) {
506 $url .= "#{$this->fragment}";
507 }
508
509 return $url;
510 }
511 }
512