Skip to content

Commit

Permalink
Added URL rewrites data to the product interface
Browse files Browse the repository at this point in the history
  • Loading branch information
rogyar committed Jun 30, 2018
1 parent f947cad commit d6d0872
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 102 deletions.
1 change: 1 addition & 0 deletions app/code/Magento/CatalogGraphQl/etc/module.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<module name="Magento_GraphQl"/>
<module name="Magento_StoreGraphQl"/>
<module name="Magento_EavGraphQl"/>
<module name="Magento_UrlRewriteGraphQl"/>
</sequence>
</module>
</config>
1 change: 1 addition & 0 deletions app/code/Magento/CatalogGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\
manufacturer: Int @doc(description: "A number representing the product's manufacturer")
categories: [CategoryInterface] @doc(description: "The categories assigned to a product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Categories")
canonical_url: String @doc(description: "Canonical URL") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CanonicalUrl")
url_rewrites: [UrlRewrite] @doc(description: "URL rewrites list") @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\UrlRewrite")
}

interface PhysicalProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") @doc(description: "PhysicalProductInterface contains attributes specific to tangible products") {
Expand Down
161 changes: 161 additions & 0 deletions app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\UrlRewriteGraphQl\Model\Resolver;

use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\Resolver\Value;
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\UrlRewrite\Model\UrlFinderInterface;
use Magento\UrlRewriteGraphQl\Model\Resolver\UrlRewrite\CustomUrlLocatorInterface;

/**
* UrlRewrite field resolver, used for GraphQL request processing.
*/
class EntityUrl implements ResolverInterface
{
/**
* @var UrlFinderInterface
*/
private $urlFinder;

/**
* @var StoreManagerInterface
*/
private $storeManager;

/**
* @var ValueFactory
*/
private $valueFactory;

/**
* @var CustomUrlLocatorInterface
*/
private $customUrlLocator;

/**
* @param UrlFinderInterface $urlFinder
* @param StoreManagerInterface $storeManager
* @param ValueFactory $valueFactory
* @param CustomUrlLocatorInterface $customUrlLocator
*/
public function __construct(
UrlFinderInterface $urlFinder,
StoreManagerInterface $storeManager,
ValueFactory $valueFactory,
CustomUrlLocatorInterface $customUrlLocator
) {
$this->urlFinder = $urlFinder;
$this->storeManager = $storeManager;
$this->valueFactory = $valueFactory;
$this->customUrlLocator = $customUrlLocator;
}

/**
* {@inheritdoc}
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
) : Value {
$result = function () {
return null;
};

if (isset($args['url'])) {
$url = $args['url'];
if (substr($url, 0, 1) === '/' && $url !== '/') {
$url = ltrim($url, '/');
}
$customUrl = $this->customUrlLocator->locateUrl($url);
$url = $customUrl ?: $url;
$urlRewrite = $this->findCanonicalUrl($url);
if ($urlRewrite) {
$urlRewriteReturnArray = [
'id' => $urlRewrite->getEntityId(),
'canonical_url' => $urlRewrite->getTargetPath(),
'type' => $this->sanitizeType($urlRewrite->getEntityType())
];
$result = function () use ($urlRewriteReturnArray) {
return $urlRewriteReturnArray;
};
}
}
return $this->valueFactory->create($result);
}

/**
* Find the canonical url passing through all redirects if any
*
* @param string $requestPath
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
*/
private function findCanonicalUrl(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
{
$urlRewrite = $this->findUrlFromRequestPath($requestPath);
if ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
while ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
$urlRewrite = $this->findUrlFromRequestPath($urlRewrite->getTargetPath());
}
}
if (!$urlRewrite) {
$urlRewrite = $this->findUrlFromTargetPath($requestPath);
}

return $urlRewrite;
}

/**
* Find a url from a request url on the current store
*
* @param string $requestPath
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
*/
private function findUrlFromRequestPath(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
{
return $this->urlFinder->findOneByData(
[
'request_path' => $requestPath,
'store_id' => $this->storeManager->getStore()->getId()
]
);
}

/**
* Find a url from a target url on the current store
*
* @param string $targetPath
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
*/
private function findUrlFromTargetPath(string $targetPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
{
return $this->urlFinder->findOneByData(
[
'target_path' => $targetPath,
'store_id' => $this->storeManager->getStore()->getId()
]
);
}

/**
* Sanitize the type to fit schema specifications
*
* @param string $type
* @return string
*/
private function sanitizeType(string $type) : string
{
return strtoupper(str_replace('-', '_', $type));
}
}
146 changes: 45 additions & 101 deletions app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,51 +12,31 @@
use Magento\Framework\GraphQl\Query\Resolver\Value;
use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\Model\AbstractModel;
use Magento\UrlRewrite\Model\UrlFinderInterface;
use Magento\UrlRewriteGraphQl\Model\Resolver\UrlRewrite\CustomUrlLocatorInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite as UrlRewriteDTO;

/**
* UrlRewrite field resolver, used for GraphQL request processing.
*/
class UrlRewrite implements ResolverInterface
{
/**
* @var UrlFinderInterface
*/
private $urlFinder;

/**
* @var StoreManagerInterface
*/
private $storeManager;

/**
* @var ValueFactory
*/
private $valueFactory;

/**
* @var CustomUrlLocatorInterface
*/
private $customUrlLocator;

/**
* @param UrlFinderInterface $urlFinder
* @param StoreManagerInterface $storeManager
* @param ValueFactory $valueFactory
* @param CustomUrlLocatorInterface $customUrlLocator
* @param UrlFinderInterface $urlFinder
*/
public function __construct(
UrlFinderInterface $urlFinder,
StoreManagerInterface $storeManager,
ValueFactory $valueFactory,
CustomUrlLocatorInterface $customUrlLocator
UrlFinderInterface $urlFinder
) {
$this->urlFinder = $urlFinder;
$this->storeManager = $storeManager;
$this->valueFactory = $valueFactory;
$this->customUrlLocator = $customUrlLocator;
$this->urlFinder = $urlFinder;
}

/**
Expand All @@ -68,94 +48,58 @@ public function resolve(
ResolveInfo $info,
array $value = null,
array $args = null
) : Value {
$result = function () {
return null;
};

if (isset($args['url'])) {
$url = $args['url'];
if (substr($url, 0, 1) === '/' && $url !== '/') {
$url = ltrim($url, '/');
}
$customUrl = $this->customUrlLocator->locateUrl($url);
$url = $customUrl ?: $url;
$urlRewrite = $this->findCanonicalUrl($url);
if ($urlRewrite) {
$urlRewriteReturnArray = [
'id' => $urlRewrite->getEntityId(),
'canonical_url' => $urlRewrite->getTargetPath(),
'type' => $this->sanitizeType($urlRewrite->getEntityType())
];
$result = function () use ($urlRewriteReturnArray) {
return $urlRewriteReturnArray;
};
}
): Value {
if (!isset($value['model'])) {
$result = function () {
return null;
};
return $this->valueFactory->create($result);
}
return $this->valueFactory->create($result);
}

/**
* Find the canonical url passing through all redirects if any
*
* @param string $requestPath
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
*/
private function findCanonicalUrl(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
{
$urlRewrite = $this->findUrlFromRequestPath($requestPath);
if ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
while ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
$urlRewrite = $this->findUrlFromRequestPath($urlRewrite->getTargetPath());
/** @var AbstractModel $entity */
$entity = $value['model'];
$entityId = $entity->getEntityId();

$urlRewritesCollection = $this->urlFinder->findAllByData([UrlRewriteDTO::ENTITY_ID => $entityId]);
$urlRewrites = [];

/** @var UrlRewriteDTO $urlRewrite */
foreach ($urlRewritesCollection as $urlRewrite) {
if ($urlRewrite->getRedirectType() !== 0) {
continue;
}

$urlRewrites[] = [
'url' => $urlRewrite->getRequestPath(),
'parameters' => $this->getUrlParameters($urlRewrite->getTargetPath())
];
}
if (!$urlRewrite) {
$urlRewrite = $this->findUrlFromTargetPath($requestPath);
}

return $urlRewrite;
}

/**
* Find a url from a request url on the current store
*
* @param string $requestPath
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
*/
private function findUrlFromRequestPath(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
{
return $this->urlFinder->findOneByData(
[
'request_path' => $requestPath,
'store_id' => $this->storeManager->getStore()->getId()
]
);
$result = function () use ($urlRewrites) {
return $urlRewrites;
};

return $this->valueFactory->create($result);
}

/**
* Find a url from a target url on the current store
* Parses target path and extracts parameters
*
* @param string $targetPath
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
* @return array
*/
private function findUrlFromTargetPath(string $targetPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
private function getUrlParameters(string $targetPath): array
{
return $this->urlFinder->findOneByData(
[
'target_path' => $targetPath,
'store_id' => $this->storeManager->getStore()->getId()
]
);
}
$urlParameters = [];
$targetPathParts = explode('/', trim($targetPath, '/'));

/**
* Sanitize the type to fit schema specifications
*
* @param string $type
* @return string
*/
private function sanitizeType(string $type) : string
{
return strtoupper(str_replace('-', '_', $type));
for ($i = 3; ($i < sizeof($targetPathParts) - 1); $i += 2) {
$urlParameters[] = [
'name' => $targetPathParts[$i],
'value' => $targetPathParts[$i + 1]
];
}

return $urlParameters;
}
}
12 changes: 11 additions & 1 deletion app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,18 @@ type EntityUrl @doc(description: "EntityUrl is an output object containing the `
}

type Query {
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")
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")
}

enum UrlRewriteEntityTypeEnum {
}

type UrlRewrite @doc(description: "The object contains URL rewrite details") {
url: String @doc(description: "Request URL")
parameters: [HttpQueryParameter] @doc(description: "Request parameters")
}

type HttpQueryParameter @doc(description: "The object details of target path parameters") {
name: String @doc(description: "Parameter name")
value: String @doc(description: "Parameter value")
}

0 comments on commit d6d0872

Please sign in to comment.