@@ -31,6 +31,11 @@ class EntityUrl implements ResolverInterface
3131 */
3232 private $ customUrlLocator ;
3333
34+ /**
35+ * @var int
36+ */
37+ private $ redirectType ;
38+
3439 /**
3540 * @param UrlFinderInterface $urlFinder
3641 * @param CustomUrlLocatorInterface $customUrlLocator
@@ -57,49 +62,83 @@ public function resolve(
5762 throw new GraphQlInputException (__ ('"url" argument should be specified and not empty ' ));
5863 }
5964
65+ $ storeId = (int )$ context ->getExtensionAttributes ()->getStore ()->getId ();
6066 $ result = null ;
6167 $ url = $ args ['url ' ];
6268 if (substr ($ url , 0 , 1 ) === '/ ' && $ url !== '/ ' ) {
6369 $ url = ltrim ($ url , '/ ' );
6470 }
71+ $ this ->redirectType = 0 ;
6572 $ customUrl = $ this ->customUrlLocator ->locateUrl ($ url );
6673 $ url = $ customUrl ?: $ url ;
67- $ urlRewrite = $ this ->findCanonicalUrl ($ url , (int )$ context ->getExtensionAttributes ()->getStore ()->getId ());
68- if ($ urlRewrite ) {
69- if (!$ urlRewrite ->getEntityId ()) {
74+ $ finalUrlRewrite = $ this ->findFinalUrl ($ url , $ storeId );
75+ if ($ finalUrlRewrite ) {
76+ $ relativeUrl = $ finalUrlRewrite ->getRequestPath ();
77+ $ resultArray = $ this ->rewriteCustomUrls ($ finalUrlRewrite , $ storeId ) ?? [
78+ 'id ' => $ finalUrlRewrite ->getEntityId (),
79+ 'canonical_url ' => $ relativeUrl ,
80+ 'relative_url ' => $ relativeUrl ,
81+ 'redirectCode ' => $ this ->redirectType ,
82+ 'type ' => $ this ->sanitizeType ($ finalUrlRewrite ->getEntityType ())
83+ ];
84+
85+ if (empty ($ resultArray ['id ' ])) {
7086 throw new GraphQlNoSuchEntityException (
7187 __ ('No such entity found with matching URL key: %url ' , ['url ' => $ url ])
7288 );
7389 }
74- $ result = [
75- 'id ' => $ urlRewrite ->getEntityId (),
76- 'canonical_url ' => $ urlRewrite ->getTargetPath (),
77- 'relative_url ' => $ urlRewrite ->getTargetPath (),
78- 'type ' => $ this ->sanitizeType ($ urlRewrite ->getEntityType ())
79- ];
90+
91+ $ result = $ resultArray ;
8092 }
8193 return $ result ;
8294 }
8395
8496 /**
85- * Find the canonical url passing through all redirects if any
97+ * Handle custom urls with and without redirects
98+ *
99+ * @param UrlRewrite $finalUrlRewrite
100+ * @param int $storeId
101+ * @return array|null
102+ */
103+ private function rewriteCustomUrls (UrlRewrite $ finalUrlRewrite , int $ storeId ): ?array
104+ {
105+ if ($ finalUrlRewrite ->getEntityType () === 'custom ' || !($ finalUrlRewrite ->getEntityId () > 0 )) {
106+ $ finalCustomUrlRewrite = clone $ finalUrlRewrite ;
107+ $ finalUrlRewrite = $ this ->findFinalUrl ($ finalCustomUrlRewrite ->getTargetPath (), $ storeId , true );
108+ $ relativeUrl =
109+ $ finalCustomUrlRewrite ->getRedirectType () == 0
110+ ? $ finalCustomUrlRewrite ->getRequestPath () : $ finalUrlRewrite ->getRequestPath ();
111+ return [
112+ 'id ' => $ finalUrlRewrite ->getEntityId (),
113+ 'canonical_url ' => $ relativeUrl ,
114+ 'relative_url ' => $ relativeUrl ,
115+ 'redirectCode ' => $ finalCustomUrlRewrite ->getRedirectType (),
116+ 'type ' => $ this ->sanitizeType ($ finalUrlRewrite ->getEntityType ())
117+ ];
118+ }
119+ return null ;
120+ }
121+
122+ /**
123+ * Find the final url passing through all redirects if any
86124 *
87125 * @param string $requestPath
88126 * @param int $storeId
127+ * @param bool $findCustom
89128 * @return UrlRewrite|null
90129 */
91- private function findCanonicalUrl (string $ requestPath , int $ storeId) : ?UrlRewrite
130+ private function findFinalUrl (string $ requestPath , int $ storeId, bool $ findCustom = false ) : ?UrlRewrite
92131 {
93132 $ urlRewrite = $ this ->findUrlFromRequestPath ($ requestPath , $ storeId );
94- if ($ urlRewrite && $ urlRewrite ->getRedirectType () > 0 ) {
133+ if ($ urlRewrite ) {
134+ $ this ->redirectType = $ urlRewrite ->getRedirectType ();
95135 while ($ urlRewrite && $ urlRewrite ->getRedirectType () > 0 ) {
96136 $ urlRewrite = $ this ->findUrlFromRequestPath ($ urlRewrite ->getTargetPath (), $ storeId );
97137 }
98- }
99- if (!$ urlRewrite ) {
138+ } else {
100139 $ urlRewrite = $ this ->findUrlFromTargetPath ($ requestPath , $ storeId );
101140 }
102- if ($ urlRewrite && !$ urlRewrite ->getEntityId () && !$ urlRewrite ->getIsAutogenerated ()) {
141+ if ($ urlRewrite && ( $ findCustom && !$ urlRewrite ->getEntityId () && !$ urlRewrite ->getIsAutogenerated () )) {
103142 $ urlRewrite = $ this ->findUrlFromTargetPath ($ urlRewrite ->getTargetPath (), $ storeId );
104143 }
105144
@@ -113,7 +152,7 @@ private function findCanonicalUrl(string $requestPath, int $storeId) : ?UrlRewri
113152 * @param int $storeId
114153 * @return UrlRewrite|null
115154 */
116- private function findUrlFromRequestPath (string $ requestPath , int $ storeId ) : ?UrlRewrite
155+ private function findUrlFromRequestPath (string $ requestPath , int $ storeId ): ?UrlRewrite
117156 {
118157 return $ this ->urlFinder ->findOneByData (
119158 [
@@ -130,7 +169,7 @@ private function findUrlFromRequestPath(string $requestPath, int $storeId) : ?Ur
130169 * @param int $storeId
131170 * @return UrlRewrite|null
132171 */
133- private function findUrlFromTargetPath (string $ targetPath , int $ storeId ) : ?UrlRewrite
172+ private function findUrlFromTargetPath (string $ targetPath , int $ storeId ): ?UrlRewrite
134173 {
135174 return $ this ->urlFinder ->findOneByData (
136175 [
0 commit comments