UrlHelper.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\HttpFoundation;
  11. use Symfony\Component\Routing\RequestContext;
  12. use Symfony\Component\Routing\RequestContextAwareInterface;
  13. /**
  14. * A helper service for manipulating URLs within and outside the request scope.
  15. *
  16. * @author Valentin Udaltsov <udaltsov.valentin@gmail.com>
  17. */
  18. final class UrlHelper
  19. {
  20. public function __construct(
  21. private RequestStack $requestStack,
  22. private RequestContextAwareInterface|RequestContext|null $requestContext = null,
  23. ) {
  24. }
  25. public function getAbsoluteUrl(string $path): string
  26. {
  27. if (str_contains($path, '://') || str_starts_with($path, '//')) {
  28. return $path;
  29. }
  30. if (null === $request = $this->requestStack->getMainRequest()) {
  31. return $this->getAbsoluteUrlFromContext($path);
  32. }
  33. if ('#' === $path[0]) {
  34. $path = $request->getRequestUri().$path;
  35. } elseif ('?' === $path[0]) {
  36. $path = $request->getPathInfo().$path;
  37. }
  38. if (!$path || '/' !== $path[0]) {
  39. $prefix = $request->getPathInfo();
  40. $last = \strlen($prefix) - 1;
  41. if ($last !== $pos = strrpos($prefix, '/')) {
  42. $prefix = substr($prefix, 0, $pos).'/';
  43. }
  44. return $request->getUriForPath($prefix.$path);
  45. }
  46. return $request->getSchemeAndHttpHost().$path;
  47. }
  48. public function getRelativePath(string $path): string
  49. {
  50. if (str_contains($path, '://') || str_starts_with($path, '//')) {
  51. return $path;
  52. }
  53. if (null === $request = $this->requestStack->getMainRequest()) {
  54. return $path;
  55. }
  56. return $request->getRelativeUriForPath($path);
  57. }
  58. private function getAbsoluteUrlFromContext(string $path): string
  59. {
  60. if (null === $context = $this->requestContext) {
  61. return $path;
  62. }
  63. if ($context instanceof RequestContextAwareInterface) {
  64. $context = $context->getContext();
  65. }
  66. if ('' === $host = $context->getHost()) {
  67. return $path;
  68. }
  69. $scheme = $context->getScheme();
  70. $port = '';
  71. if ('http' === $scheme && 80 !== $context->getHttpPort()) {
  72. $port = ':'.$context->getHttpPort();
  73. } elseif ('https' === $scheme && 443 !== $context->getHttpsPort()) {
  74. $port = ':'.$context->getHttpsPort();
  75. }
  76. if ('#' === $path[0]) {
  77. $queryString = $context->getQueryString();
  78. $path = $context->getPathInfo().($queryString ? '?'.$queryString : '').$path;
  79. } elseif ('?' === $path[0]) {
  80. $path = $context->getPathInfo().$path;
  81. }
  82. if ('/' !== $path[0]) {
  83. $path = rtrim($context->getBaseUrl(), '/').'/'.$path;
  84. }
  85. return $scheme.'://'.$host.$port.$path;
  86. }
  87. }