Skip to content

Commit f1a2616

Browse files
author
Valeriy Naida
authored
ENGCOM-3072: Added URL rewrites data to the product interface #107
2 parents 0571603 + b96a844 commit f1a2616

File tree

7 files changed

+370
-112
lines changed

7 files changed

+370
-112
lines changed

app/code/Magento/CatalogUrlRewriteGraphQl/etc/module.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,10 @@
66
*/
77
-->
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
9-
<module name="Magento_CatalogUrlRewriteGraphQl" />
9+
<module name="Magento_CatalogUrlRewriteGraphQl" >
10+
<sequence>
11+
<module name="Magento_UrlRewriteGraphQl"/>
12+
<module name="Magento_CatalogGraphQl"/>
13+
</sequence>
14+
</module>
1015
</config>

app/code/Magento/CatalogUrlRewriteGraphQl/etc/schema.graphqls

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
interface ProductInterface {
55
url_key: String @doc(description: "The part of the URL that identifies the product")
66
url_path: String @doc(description: "The part of the URL that precedes the url_key")
7+
url_rewrites: [UrlRewrite] @doc(description: "URL rewrites list") @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\UrlRewrite")
78
}
89

910
input ProductFilterInput {
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\UrlRewriteGraphQl\Model\Resolver;
9+
10+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
11+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
12+
use Magento\Framework\GraphQl\Config\Element\Field;
13+
use Magento\Framework\GraphQl\Query\ResolverInterface;
14+
use Magento\Store\Model\StoreManagerInterface;
15+
use Magento\UrlRewrite\Model\UrlFinderInterface;
16+
use Magento\UrlRewriteGraphQl\Model\Resolver\UrlRewrite\CustomUrlLocatorInterface;
17+
18+
/**
19+
* UrlRewrite field resolver, used for GraphQL request processing.
20+
*/
21+
class EntityUrl implements ResolverInterface
22+
{
23+
/**
24+
* @var UrlFinderInterface
25+
*/
26+
private $urlFinder;
27+
28+
/**
29+
* @var StoreManagerInterface
30+
*/
31+
private $storeManager;
32+
33+
/**
34+
* @var CustomUrlLocatorInterface
35+
*/
36+
private $customUrlLocator;
37+
38+
/**
39+
* @param UrlFinderInterface $urlFinder
40+
* @param StoreManagerInterface $storeManager
41+
* @param CustomUrlLocatorInterface $customUrlLocator
42+
*/
43+
public function __construct(
44+
UrlFinderInterface $urlFinder,
45+
StoreManagerInterface $storeManager,
46+
CustomUrlLocatorInterface $customUrlLocator
47+
) {
48+
$this->urlFinder = $urlFinder;
49+
$this->storeManager = $storeManager;
50+
$this->customUrlLocator = $customUrlLocator;
51+
}
52+
53+
/**
54+
* @inheritdoc
55+
*/
56+
public function resolve(
57+
Field $field,
58+
$context,
59+
ResolveInfo $info,
60+
array $value = null,
61+
array $args = null
62+
) {
63+
if (!isset($args['url']) || empty(trim($args['url']))) {
64+
throw new GraphQlInputException(__('"url" argument should be specified and not empty'));
65+
}
66+
67+
$result = null;
68+
$url = $args['url'];
69+
if (substr($url, 0, 1) === '/' && $url !== '/') {
70+
$url = ltrim($url, '/');
71+
}
72+
$customUrl = $this->customUrlLocator->locateUrl($url);
73+
$url = $customUrl ?: $url;
74+
$urlRewrite = $this->findCanonicalUrl($url);
75+
if ($urlRewrite) {
76+
$result = [
77+
'id' => $urlRewrite->getEntityId(),
78+
'canonical_url' => $urlRewrite->getTargetPath(),
79+
'type' => $this->sanitizeType($urlRewrite->getEntityType())
80+
];
81+
}
82+
return $result;
83+
}
84+
85+
/**
86+
* Find the canonical url passing through all redirects if any
87+
*
88+
* @param string $requestPath
89+
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
90+
*/
91+
private function findCanonicalUrl(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
92+
{
93+
$urlRewrite = $this->findUrlFromRequestPath($requestPath);
94+
if ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
95+
while ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
96+
$urlRewrite = $this->findUrlFromRequestPath($urlRewrite->getTargetPath());
97+
}
98+
}
99+
if (!$urlRewrite) {
100+
$urlRewrite = $this->findUrlFromTargetPath($requestPath);
101+
}
102+
103+
return $urlRewrite;
104+
}
105+
106+
/**
107+
* Find a url from a request url on the current store
108+
*
109+
* @param string $requestPath
110+
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
111+
*/
112+
private function findUrlFromRequestPath(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
113+
{
114+
return $this->urlFinder->findOneByData(
115+
[
116+
'request_path' => $requestPath,
117+
'store_id' => $this->storeManager->getStore()->getId()
118+
]
119+
);
120+
}
121+
122+
/**
123+
* Find a url from a target url on the current store
124+
*
125+
* @param string $targetPath
126+
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
127+
*/
128+
private function findUrlFromTargetPath(string $targetPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
129+
{
130+
return $this->urlFinder->findOneByData(
131+
[
132+
'target_path' => $targetPath,
133+
'store_id' => $this->storeManager->getStore()->getId()
134+
]
135+
);
136+
}
137+
138+
/**
139+
* Sanitize the type to fit schema specifications
140+
*
141+
* @param string $type
142+
* @return string
143+
*/
144+
private function sanitizeType(string $type) : string
145+
{
146+
return strtoupper(str_replace('-', '_', $type));
147+
}
148+
}

app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php

Lines changed: 36 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
1212
use Magento\Framework\GraphQl\Config\Element\Field;
1313
use Magento\Framework\GraphQl\Query\ResolverInterface;
14-
use Magento\Store\Model\StoreManagerInterface;
14+
use Magento\Framework\Model\AbstractModel;
1515
use Magento\UrlRewrite\Model\UrlFinderInterface;
16-
use Magento\UrlRewriteGraphQl\Model\Resolver\UrlRewrite\CustomUrlLocatorInterface;
16+
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite as UrlRewriteDTO;
1717

1818
/**
19-
* UrlRewrite field resolver, used for GraphQL request processing.
19+
* Returns URL rewrites list for the specified product
2020
*/
2121
class UrlRewrite implements ResolverInterface
2222
{
@@ -25,29 +25,13 @@ class UrlRewrite implements ResolverInterface
2525
*/
2626
private $urlFinder;
2727

28-
/**
29-
* @var StoreManagerInterface
30-
*/
31-
private $storeManager;
32-
33-
/**
34-
* @var CustomUrlLocatorInterface
35-
*/
36-
private $customUrlLocator;
37-
3828
/**
3929
* @param UrlFinderInterface $urlFinder
40-
* @param StoreManagerInterface $storeManager
41-
* @param CustomUrlLocatorInterface $customUrlLocator
4230
*/
4331
public function __construct(
44-
UrlFinderInterface $urlFinder,
45-
StoreManagerInterface $storeManager,
46-
CustomUrlLocatorInterface $customUrlLocator
32+
UrlFinderInterface $urlFinder
4733
) {
4834
$this->urlFinder = $urlFinder;
49-
$this->storeManager = $storeManager;
50-
$this->customUrlLocator = $customUrlLocator;
5135
}
5236

5337
/**
@@ -59,90 +43,51 @@ public function resolve(
5943
ResolveInfo $info,
6044
array $value = null,
6145
array $args = null
62-
) {
63-
if (!isset($args['url']) || empty(trim($args['url']))) {
64-
throw new GraphQlInputException(__('"url" argument should be specified and not empty'));
46+
): array {
47+
if (!isset($value['model'])) {
48+
throw new GraphQlInputException(__('"model" value should be specified'));
6549
}
6650

67-
$result = null;
68-
$url = $args['url'];
69-
if (substr($url, 0, 1) === '/' && $url !== '/') {
70-
$url = ltrim($url, '/');
71-
}
72-
$customUrl = $this->customUrlLocator->locateUrl($url);
73-
$url = $customUrl ?: $url;
74-
$urlRewrite = $this->findCanonicalUrl($url);
75-
if ($urlRewrite) {
76-
$result = [
77-
'id' => $urlRewrite->getEntityId(),
78-
'relative_url' => $urlRewrite->getTargetPath(),
79-
'type' => $this->sanitizeType($urlRewrite->getEntityType())
80-
];
81-
}
82-
return $result;
83-
}
51+
/** @var AbstractModel $entity */
52+
$entity = $value['model'];
53+
$entityId = $entity->getEntityId();
8454

85-
/**
86-
* Find the canonical url passing through all redirects if any
87-
*
88-
* @param string $requestPath
89-
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
90-
*/
91-
private function findCanonicalUrl(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
92-
{
93-
$urlRewrite = $this->findUrlFromRequestPath($requestPath);
94-
if ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
95-
while ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
96-
$urlRewrite = $this->findUrlFromRequestPath($urlRewrite->getTargetPath());
55+
$urlRewriteCollection = $this->urlFinder->findAllByData([UrlRewriteDTO::ENTITY_ID => $entityId]);
56+
$urlRewrites = [];
57+
58+
/** @var UrlRewriteDTO $urlRewrite */
59+
foreach ($urlRewriteCollection as $urlRewrite) {
60+
if ($urlRewrite->getRedirectType() !== 0) {
61+
continue;
9762
}
63+
64+
$urlRewrites[] = [
65+
'url' => $urlRewrite->getRequestPath(),
66+
'parameters' => $this->getUrlParameters($urlRewrite->getTargetPath())
67+
];
9868
}
99-
if (!$urlRewrite) {
100-
$urlRewrite = $this->findUrlFromTargetPath($requestPath);
101-
}
102-
103-
return $urlRewrite;
104-
}
10569

106-
/**
107-
* Find a url from a request url on the current store
108-
*
109-
* @param string $requestPath
110-
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
111-
*/
112-
private function findUrlFromRequestPath(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
113-
{
114-
return $this->urlFinder->findOneByData(
115-
[
116-
'request_path' => $requestPath,
117-
'store_id' => $this->storeManager->getStore()->getId()
118-
]
119-
);
70+
return $urlRewrites;
12071
}
12172

12273
/**
123-
* Find a url from a target url on the current store
74+
* Parses target path and extracts parameters
12475
*
12576
* @param string $targetPath
126-
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
77+
* @return array
12778
*/
128-
private function findUrlFromTargetPath(string $targetPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
79+
private function getUrlParameters(string $targetPath): array
12980
{
130-
return $this->urlFinder->findOneByData(
131-
[
132-
'target_path' => $targetPath,
133-
'store_id' => $this->storeManager->getStore()->getId()
134-
]
135-
);
136-
}
81+
$urlParameters = [];
82+
$targetPathParts = explode('/', trim($targetPath, '/'));
13783

138-
/**
139-
* Sanitize the type to fit schema specifications
140-
*
141-
* @param string $type
142-
* @return string
143-
*/
144-
private function sanitizeType(string $type) : string
145-
{
146-
return strtoupper(str_replace('-', '_', $type));
84+
for ($i = 3; ($i < sizeof($targetPathParts) - 1); $i += 2) {
85+
$urlParameters[] = [
86+
'name' => $targetPathParts[$i],
87+
'value' => $targetPathParts[$i + 1]
88+
];
89+
}
90+
91+
return $urlParameters;
14792
}
14893
}
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
11
# Copyright © Magento, Inc. All rights reserved.
22
# See COPYING.txt for license details.
33

4-
type EntityUrl @doc(description: "EntityUrl is an output object containing the `id`, `relative_url`, and `type` attributes") {
4+
type EntityUrl @doc(description: "EntityUrl is an output object containing the `id`, `canonical_url`, and `type` attributes") {
55
id: Int @doc(description: "The ID assigned to the object associated with the specified url. This could be a product ID, category ID, or page ID.")
6-
relative_url: String @doc(description: "The internal relative URL. If the specified url is a redirect, the query returns the redirected URL, not the original.")
6+
canonical_url: String @doc(description: "The internal relative URL. If the specified url is a redirect, the query returns the redirected URL, not the original.")
77
type: UrlRewriteEntityTypeEnum @doc(description: "One of PRODUCT, CATEGORY, or CMS_PAGE.")
88
}
99

1010
type Query {
11-
urlResolver(url: String!): EntityUrl @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\UrlRewrite") @doc(description: "The urlResolver query returns the relative URL for a specified product, category or CMS page")
11+
urlResolver(url: String!): EntityUrl @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\EntityUrl") @doc(description: "The urlResolver query returns the relative URL for a specified product, category or CMS page")
1212
}
1313

1414
enum UrlRewriteEntityTypeEnum {
1515
}
16+
17+
type UrlRewrite @doc(description: "The object contains URL rewrite details") {
18+
url: String @doc(description: "Request URL")
19+
parameters: [HttpQueryParameter] @doc(description: "Request parameters")
20+
}
21+
22+
type HttpQueryParameter @doc(description: "The object details of target path parameters") {
23+
name: String @doc(description: "Parameter name")
24+
value: String @doc(description: "Parameter value")
25+
}

0 commit comments

Comments
 (0)