1616use ApiPlatform \Metadata \Exception \InvalidArgumentException ;
1717use ApiPlatform \Metadata \UrlGeneratorInterface ;
1818use ApiPlatform \State \Util \RequestParser ;
19+ use Uri \InvalidUriException ;
20+ use Uri \Rfc3986 \Uri ;
1921
2022/**
2123 * Parses and creates IRIs.
@@ -30,12 +32,35 @@ private function __construct()
3032 {
3133 }
3234
35+ public static function parseIri (string $ iri , string $ pageParameterName ): array
36+ {
37+ if (PHP_VERSION_ID < 80500 || !\class_exists (Uri::class)) {
38+ return self ::parseLegacyIri ($ iri , $ pageParameterName );
39+ }
40+
41+ try {
42+ $ uri = new Uri ($ iri );
43+ } catch (InvalidUriException $ e ) {
44+ throw new InvalidArgumentException (\sprintf ('The request URI "%s" is malformed. ' , $ iri ), previous: $ e );
45+ }
46+
47+ $ parameters = [];
48+ if (null !== $ query = $ uri ->getQuery ()) {
49+ $ parameters = RequestParser::parseRequestParams ($ query );
50+
51+ // Remove existing page parameter
52+ unset($ parameters [$ pageParameterName ]);
53+ }
54+
55+ return ['uri ' => $ uri , 'parameters ' => $ parameters ];
56+ }
57+
3358 /**
3459 * Parses and standardizes the request IRI.
3560 *
3661 * @throws InvalidArgumentException
3762 */
38- public static function parseIri (string $ iri , string $ pageParameterName ): array
63+ private static function parseLegacyIri (string $ iri , string $ pageParameterName ): array
3964 {
4065 $ parts = parse_url ($ iri );
4166 if (false === $ parts ) {
@@ -58,14 +83,29 @@ public static function parseIri(string $iri, string $pageParameterName): array
5883 *
5984 * @param int $urlGenerationStrategy
6085 */
61- public static function createIri (array $ parts , array $ parameters , ?string $ pageParameterName = null , ?float $ page = null , $ urlGenerationStrategy = UrlGeneratorInterface::ABS_PATH ): string
86+ public static function createIri (array | Uri $ parts , array $ parameters , ?string $ pageParameterName = null , ?float $ page = null , $ urlGenerationStrategy = UrlGeneratorInterface::ABS_PATH ): string
6287 {
6388 if (null !== $ page && null !== $ pageParameterName ) {
6489 $ parameters [$ pageParameterName ] = $ page ;
6590 }
6691
6792 $ query = http_build_query ($ parameters , '' , '& ' , \PHP_QUERY_RFC3986 );
68- $ parts ['query ' ] = preg_replace ('/%5B\d+%5D/ ' , '%5B%5D ' , $ query );
93+ $ queryParts = preg_replace ('/%5B\d+%5D/ ' , '%5B%5D ' , $ query );
94+
95+ if ($ parts instanceof Uri) {
96+ $ uri = $ parts
97+ ->withQuery ('' !== $ queryParts ? $ queryParts : null )
98+ ->withScheme (UrlGeneratorInterface::ABS_URL === $ urlGenerationStrategy && null === $ parts ->getScheme () ? ($ parts ->getPort () === 443 ? 'https ' : 'http ' ) : null )
99+ ;
100+
101+ if (null === $ urlGenerationStrategy || UrlGeneratorInterface::NET_PATH === $ urlGenerationStrategy ) {
102+ $ uri = $ uri ->withScheme (null )->withUserInfo (null )->withHost (null )->withPort (null );
103+ }
104+
105+ return $ uri ->toString ();
106+ }
107+
108+ $ parts ['query ' ] = $ queryParts ;
69109
70110 $ url = '' ;
71111 if ((UrlGeneratorInterface::ABS_URL === $ urlGenerationStrategy || UrlGeneratorInterface::NET_PATH === $ urlGenerationStrategy ) && isset ($ parts ['host ' ])) {
0 commit comments