PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / trunk
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration vtrunk
2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 1.45 All 41 releases
fluent-boards / vendor / wpfluent / framework / src / WPFluent / Http / URL.php

URL.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration trunk, at vendor/wpfluent/framework/src/WPFluent/Http/URL.php

510 lines 8.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBoards\Framework\Http;
4
5 use Exception;
6 use InvalidArgumentException;
7 use FluentBoards\Framework\Support\Util;
8 use FluentBoards\Framework\Foundation\App;
9 use FluentBoards\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 public function fromFile(string $path, bool $checkFile = false): string
308 {
309 return Util::pathToUrl($path, $checkFile);
310 }
311
312 /**
313 * Generate a URL from a named route.
314 *
315 * @param string $name
316 * @param array $params
317 * @param array $query
318 * @return string|null
319 */
320 public function route($name, $params = [], $query = [])
321 {
322 return $this->generator->route($name, $params, $query);
323 }
324
325 /**
326 * Return a clone of the URL with a new path.
327 *
328 * @param string $path
329 * @return $this
330 */
331 public function withPath($path)
332 {
333 $clone = clone $this;
334 $clone->path = $path;
335 return $clone;
336 }
337
338 /**
339 * Return a clone of the URL with a new query.
340 *
341 * @param array|string $query An array of query params or a query string
342 * @return $this
343 */
344 public function withQuery($query)
345 {
346 $clone = clone $this;
347
348 if (is_string($query)) {
349 parse_str($query, $query);
350 }
351
352 $clone->query = $query;
353 return $clone;
354 }
355
356 /**
357 * Return a clone of the URL with a new fragment.
358 *
359 * @param string $fragment
360 * @return $this
361 */
362 public function withFragment($fragment)
363 {
364 $clone = clone $this;
365 $clone->fragment = $fragment;
366 return $clone;
367 }
368
369 /**
370 * Return a clone of the URL with a new scheme.
371 *
372 * @param string $scheme
373 * @return $this
374 */
375 public function withScheme($scheme)
376 {
377 $clone = clone $this;
378 $clone->scheme = $scheme;
379 return $clone;
380 }
381
382 /**
383 * Get the URL scheme (e.g., 'http' or 'https').
384 *
385 * @return string
386 */
387 public function scheme()
388 {
389 return $this->scheme;
390 }
391
392 /**
393 * Get the URL host.
394 *
395 * @return string|null
396 */
397 public function host()
398 {
399 return $this->host;
400 }
401
402 /**
403 * Get the URL port.
404 *
405 * @return int|null
406 */
407 public function port()
408 {
409 return $this->port;
410 }
411
412 /**
413 * Get the URL path.
414 *
415 * @return string
416 */
417 public function path()
418 {
419 return $this->path;
420 }
421
422 /**
423 * Get the URL query as an array.
424 *
425 * @return array
426 */
427 public function query()
428 {
429 return $this->query;
430 }
431
432 /**
433 * Get the URL fragment.
434 *
435 * @return string|null
436 */
437 public function fragment()
438 {
439 return $this->fragment;
440 }
441
442 /**
443 * Get the URL pass.
444 *
445 * @return string|null
446 */
447 public function pass()
448 {
449 return $this->pass;
450 }
451
452 /**
453 * Get the URL user.
454 *
455 * @return string
456 */
457 public function user()
458 {
459 return $this->user;
460 }
461
462 /**
463 * Returns the string representation of the URL object.
464 *
465 * @return string Current URL.
466 */
467 public function __toString()
468 {
469 $url = '';
470
471 if ($this->scheme) {
472 $url .= "{$this->scheme}://";
473 }
474
475 if ($this->user) {
476 $url .= $this->user;
477 if ($this->pass) {
478 $url .= ":{$this->pass}";
479 }
480 $url .= '@';
481 }
482
483 if ($this->host) {
484 $url .= $this->host;
485 }
486
487 if ($this->port) {
488 $url .= ":{$this->port}";
489 }
490
491 if ($this->path !== null) {
492 $url .= $this->path === '' || str_starts_with($this->path, '/')
493 ? $this->path
494 : '/' . $this->path;
495 }
496
497 if (!empty($this->query)) {
498 $url .= '?' . http_build_query(
499 $this->query, '', '&', PHP_QUERY_RFC3986
500 );
501 }
502
503 if ($this->fragment) {
504 $url .= "#{$this->fragment}";
505 }
506
507 return $url;
508 }
509 }
510