Skip to content

Commit d6d0872

Browse files
committed
Added URL rewrites data to the product interface
1 parent f947cad commit d6d0872

File tree

5 files changed

+219
-102
lines changed

5 files changed

+219
-102
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<module name="Magento_GraphQl"/>
1616
<module name="Magento_StoreGraphQl"/>
1717
<module name="Magento_EavGraphQl"/>
18+
<module name="Magento_UrlRewriteGraphQl"/>
1819
</sequence>
1920
</module>
2021
</config>

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\
280280
manufacturer: Int @doc(description: "A number representing the product's manufacturer")
281281
categories: [CategoryInterface] @doc(description: "The categories assigned to a product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Categories")
282282
canonical_url: String @doc(description: "Canonical URL") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CanonicalUrl")
283+
url_rewrites: [UrlRewrite] @doc(description: "URL rewrites list") @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\UrlRewrite")
283284
}
284285

285286
interface PhysicalProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") @doc(description: "PhysicalProductInterface contains attributes specific to tangible products") {
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
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\Schema\Type\ResolveInfo;
11+
use Magento\Framework\GraphQl\Config\Element\Field;
12+
use Magento\Framework\GraphQl\Query\Resolver\Value;
13+
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
14+
use Magento\Framework\GraphQl\Query\ResolverInterface;
15+
use Magento\Store\Model\StoreManagerInterface;
16+
use Magento\UrlRewrite\Model\UrlFinderInterface;
17+
use Magento\UrlRewriteGraphQl\Model\Resolver\UrlRewrite\CustomUrlLocatorInterface;
18+
19+
/**
20+
* UrlRewrite field resolver, used for GraphQL request processing.
21+
*/
22+
class EntityUrl implements ResolverInterface
23+
{
24+
/**
25+
* @var UrlFinderInterface
26+
*/
27+
private $urlFinder;
28+
29+
/**
30+
* @var StoreManagerInterface
31+
*/
32+
private $storeManager;
33+
34+
/**
35+
* @var ValueFactory
36+
*/
37+
private $valueFactory;
38+
39+
/**
40+
* @var CustomUrlLocatorInterface
41+
*/
42+
private $customUrlLocator;
43+
44+
/**
45+
* @param UrlFinderInterface $urlFinder
46+
* @param StoreManagerInterface $storeManager
47+
* @param ValueFactory $valueFactory
48+
* @param CustomUrlLocatorInterface $customUrlLocator
49+
*/
50+
public function __construct(
51+
UrlFinderInterface $urlFinder,
52+
StoreManagerInterface $storeManager,
53+
ValueFactory $valueFactory,
54+
CustomUrlLocatorInterface $customUrlLocator
55+
) {
56+
$this->urlFinder = $urlFinder;
57+
$this->storeManager = $storeManager;
58+
$this->valueFactory = $valueFactory;
59+
$this->customUrlLocator = $customUrlLocator;
60+
}
61+
62+
/**
63+
* {@inheritdoc}
64+
*/
65+
public function resolve(
66+
Field $field,
67+
$context,
68+
ResolveInfo $info,
69+
array $value = null,
70+
array $args = null
71+
) : Value {
72+
$result = function () {
73+
return null;
74+
};
75+
76+
if (isset($args['url'])) {
77+
$url = $args['url'];
78+
if (substr($url, 0, 1) === '/' && $url !== '/') {
79+
$url = ltrim($url, '/');
80+
}
81+
$customUrl = $this->customUrlLocator->locateUrl($url);
82+
$url = $customUrl ?: $url;
83+
$urlRewrite = $this->findCanonicalUrl($url);
84+
if ($urlRewrite) {
85+
$urlRewriteReturnArray = [
86+
'id' => $urlRewrite->getEntityId(),
87+
'canonical_url' => $urlRewrite->getTargetPath(),
88+
'type' => $this->sanitizeType($urlRewrite->getEntityType())
89+
];
90+
$result = function () use ($urlRewriteReturnArray) {
91+
return $urlRewriteReturnArray;
92+
};
93+
}
94+
}
95+
return $this->valueFactory->create($result);
96+
}
97+
98+
/**
99+
* Find the canonical url passing through all redirects if any
100+
*
101+
* @param string $requestPath
102+
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
103+
*/
104+
private function findCanonicalUrl(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
105+
{
106+
$urlRewrite = $this->findUrlFromRequestPath($requestPath);
107+
if ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
108+
while ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
109+
$urlRewrite = $this->findUrlFromRequestPath($urlRewrite->getTargetPath());
110+
}
111+
}
112+
if (!$urlRewrite) {
113+
$urlRewrite = $this->findUrlFromTargetPath($requestPath);
114+
}
115+
116+
return $urlRewrite;
117+
}
118+
119+
/**
120+
* Find a url from a request url on the current store
121+
*
122+
* @param string $requestPath
123+
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
124+
*/
125+
private function findUrlFromRequestPath(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
126+
{
127+
return $this->urlFinder->findOneByData(
128+
[
129+
'request_path' => $requestPath,
130+
'store_id' => $this->storeManager->getStore()->getId()
131+
]
132+
);
133+
}
134+
135+
/**
136+
* Find a url from a target url on the current store
137+
*
138+
* @param string $targetPath
139+
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
140+
*/
141+
private function findUrlFromTargetPath(string $targetPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
142+
{
143+
return $this->urlFinder->findOneByData(
144+
[
145+
'target_path' => $targetPath,
146+
'store_id' => $this->storeManager->getStore()->getId()
147+
]
148+
);
149+
}
150+
151+
/**
152+
* Sanitize the type to fit schema specifications
153+
*
154+
* @param string $type
155+
* @return string
156+
*/
157+
private function sanitizeType(string $type) : string
158+
{
159+
return strtoupper(str_replace('-', '_', $type));
160+
}
161+
}

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

Lines changed: 45 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -12,51 +12,31 @@
1212
use Magento\Framework\GraphQl\Query\Resolver\Value;
1313
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
1414
use Magento\Framework\GraphQl\Query\ResolverInterface;
15-
use Magento\Store\Model\StoreManagerInterface;
15+
use Magento\Framework\Model\AbstractModel;
1616
use Magento\UrlRewrite\Model\UrlFinderInterface;
17-
use Magento\UrlRewriteGraphQl\Model\Resolver\UrlRewrite\CustomUrlLocatorInterface;
17+
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite as UrlRewriteDTO;
1818

1919
/**
2020
* UrlRewrite field resolver, used for GraphQL request processing.
2121
*/
2222
class UrlRewrite implements ResolverInterface
2323
{
24-
/**
25-
* @var UrlFinderInterface
26-
*/
2724
private $urlFinder;
28-
29-
/**
30-
* @var StoreManagerInterface
31-
*/
32-
private $storeManager;
33-
3425
/**
3526
* @var ValueFactory
3627
*/
3728
private $valueFactory;
38-
39-
/**
40-
* @var CustomUrlLocatorInterface
41-
*/
42-
private $customUrlLocator;
4329

4430
/**
45-
* @param UrlFinderInterface $urlFinder
46-
* @param StoreManagerInterface $storeManager
4731
* @param ValueFactory $valueFactory
48-
* @param CustomUrlLocatorInterface $customUrlLocator
32+
* @param UrlFinderInterface $urlFinder
4933
*/
5034
public function __construct(
51-
UrlFinderInterface $urlFinder,
52-
StoreManagerInterface $storeManager,
5335
ValueFactory $valueFactory,
54-
CustomUrlLocatorInterface $customUrlLocator
36+
UrlFinderInterface $urlFinder
5537
) {
56-
$this->urlFinder = $urlFinder;
57-
$this->storeManager = $storeManager;
5838
$this->valueFactory = $valueFactory;
59-
$this->customUrlLocator = $customUrlLocator;
39+
$this->urlFinder = $urlFinder;
6040
}
6141

6242
/**
@@ -68,94 +48,58 @@ public function resolve(
6848
ResolveInfo $info,
6949
array $value = null,
7050
array $args = null
71-
) : Value {
72-
$result = function () {
73-
return null;
74-
};
75-
76-
if (isset($args['url'])) {
77-
$url = $args['url'];
78-
if (substr($url, 0, 1) === '/' && $url !== '/') {
79-
$url = ltrim($url, '/');
80-
}
81-
$customUrl = $this->customUrlLocator->locateUrl($url);
82-
$url = $customUrl ?: $url;
83-
$urlRewrite = $this->findCanonicalUrl($url);
84-
if ($urlRewrite) {
85-
$urlRewriteReturnArray = [
86-
'id' => $urlRewrite->getEntityId(),
87-
'canonical_url' => $urlRewrite->getTargetPath(),
88-
'type' => $this->sanitizeType($urlRewrite->getEntityType())
89-
];
90-
$result = function () use ($urlRewriteReturnArray) {
91-
return $urlRewriteReturnArray;
92-
};
93-
}
51+
): Value {
52+
if (!isset($value['model'])) {
53+
$result = function () {
54+
return null;
55+
};
56+
return $this->valueFactory->create($result);
9457
}
95-
return $this->valueFactory->create($result);
96-
}
9758

98-
/**
99-
* Find the canonical url passing through all redirects if any
100-
*
101-
* @param string $requestPath
102-
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
103-
*/
104-
private function findCanonicalUrl(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
105-
{
106-
$urlRewrite = $this->findUrlFromRequestPath($requestPath);
107-
if ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
108-
while ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
109-
$urlRewrite = $this->findUrlFromRequestPath($urlRewrite->getTargetPath());
59+
/** @var AbstractModel $entity */
60+
$entity = $value['model'];
61+
$entityId = $entity->getEntityId();
62+
63+
$urlRewritesCollection = $this->urlFinder->findAllByData([UrlRewriteDTO::ENTITY_ID => $entityId]);
64+
$urlRewrites = [];
65+
66+
/** @var UrlRewriteDTO $urlRewrite */
67+
foreach ($urlRewritesCollection as $urlRewrite) {
68+
if ($urlRewrite->getRedirectType() !== 0) {
69+
continue;
11070
}
71+
72+
$urlRewrites[] = [
73+
'url' => $urlRewrite->getRequestPath(),
74+
'parameters' => $this->getUrlParameters($urlRewrite->getTargetPath())
75+
];
11176
}
112-
if (!$urlRewrite) {
113-
$urlRewrite = $this->findUrlFromTargetPath($requestPath);
114-
}
115-
116-
return $urlRewrite;
117-
}
11877

119-
/**
120-
* Find a url from a request url on the current store
121-
*
122-
* @param string $requestPath
123-
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
124-
*/
125-
private function findUrlFromRequestPath(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
126-
{
127-
return $this->urlFinder->findOneByData(
128-
[
129-
'request_path' => $requestPath,
130-
'store_id' => $this->storeManager->getStore()->getId()
131-
]
132-
);
78+
$result = function () use ($urlRewrites) {
79+
return $urlRewrites;
80+
};
81+
82+
return $this->valueFactory->create($result);
13383
}
13484

13585
/**
136-
* Find a url from a target url on the current store
86+
* Parses target path and extracts parameters
13787
*
13888
* @param string $targetPath
139-
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
89+
* @return array
14090
*/
141-
private function findUrlFromTargetPath(string $targetPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
91+
private function getUrlParameters(string $targetPath): array
14292
{
143-
return $this->urlFinder->findOneByData(
144-
[
145-
'target_path' => $targetPath,
146-
'store_id' => $this->storeManager->getStore()->getId()
147-
]
148-
);
149-
}
93+
$urlParameters = [];
94+
$targetPathParts = explode('/', trim($targetPath, '/'));
15095

151-
/**
152-
* Sanitize the type to fit schema specifications
153-
*
154-
* @param string $type
155-
* @return string
156-
*/
157-
private function sanitizeType(string $type) : string
158-
{
159-
return strtoupper(str_replace('-', '_', $type));
96+
for ($i = 3; ($i < sizeof($targetPathParts) - 1); $i += 2) {
97+
$urlParameters[] = [
98+
'name' => $targetPathParts[$i],
99+
'value' => $targetPathParts[$i + 1]
100+
];
101+
}
102+
103+
return $urlParameters;
160104
}
161105
}

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,18 @@ type EntityUrl @doc(description: "EntityUrl is an output object containing the `
88
}
99

1010
type Query {
11-
urlResolver(url: String!): EntityUrl @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\UrlRewrite") @doc(description: "The urlResolver query returns the canonical 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 canonical 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)