<?php
declare(strict_types=1);
namespace App\Module\Api;
use App\Exception\ResourceNotFoundException;
use App\Provider\ProductProvider;
use App\Store\StoreContext;
use Denios\SharedConstant\Storage\Prefix;
use Elasticsearch\Client;
use Exception;
use Locale;
/**
* Provides methods to retrieve the url data in the action
*
* @package App\Module\Api
*/
class UrlProvider
{
/**
* @var Client
*/
private Client $esClient;
/**
* @var ProductProvider
*/
private ProductProvider $productProvider;
/**
* @var StoreContext
*/
private StoreContext $storeContext;
/**
*
* @param ProductProvider $productProvider
* @param Client $esClient
* @param StoreContext $storeContext
*/
public function __construct(ProductProvider $productProvider, Client $esClient, StoreContext $storeContext)
{
$this->productProvider = $productProvider;
$this->esClient = $esClient;
$this->storeContext = $storeContext;
}
/**
* Return the full url for a given sku.
*
* @param int $sku
*
* @throws Exception
* @throws ResourceNotFoundException
*
* @return string
*/
public function getProductUrlBySku(int $sku): string
{
$product = $this->productProvider->getProductBySku((string) $sku);
if (!$product) {
throw new ResourceNotFoundException(sprintf('Could not find a product for SKU %s', $sku));
}
if (isset($product->links->canonical)) {
return $product->links->canonical;
} elseif (isset($product->links->webshop)) {
return $product->links->webshop;
} else {
// this should never happen, because links->webshop is a required property
throw new Exception(sprintf('Product found for sku %s, but no link provided in data from database', $sku));
}
}
/**
* Return the full url for a given sku.
*
* @param int $sku
*
* @throws Exception
* @throws ResourceNotFoundException
*
* @return string
*/
public function getVariantUrlBySku(int $sku): string
{
$product = $this->productProvider->getProductBySku((string) $sku);
if (!$product) {
throw new ResourceNotFoundException(sprintf('Could not find a product for SKU %s', $sku));
}
foreach ($product->variants as $variant) {
if ($variant->sku === (string) $sku && isset($variant->links->webshop)) {
return $variant->links->webshop;
}
}
if (isset($product->links->webshop)) {
return $product->links->webshop;
} elseif (isset($product->links->canonical)) {
return $product->links->canonical;
} else {
// this should never happen, because links->webshop is a required property
throw new Exception(sprintf('Product found for sku %s, but no link provided in data from database', $sku));
}
}
/**
* Return the full url for a given magento id
*
* @param int $magentoId
*
* @throws Exception
* @throws ResourceNotFoundException
*
* @return string
*/
public function getCategoryUrlByMagentoId(int $magentoId): string
{
$index = implode('_', [
$this->storeContext->getDefaultLocale(),
strtolower(Locale::canonicalize($this->storeContext->getLocaleInfo()->getCurrentLocale())),
Prefix::CATEGORY
]);
// raw elasticsearch response
$searchRawData = $this->esClient->search([
'index' => $index,
'body' => [
'query' => [
'term' => [
'magentoId' => $magentoId
]
]
],
'size' => 1
]);
if (!isset($searchRawData['hits']['hits'][0]['_source'])) {
throw new ResourceNotFoundException(sprintf('Could not find a category for magentoId %s', $magentoId));
}
// array structure for Denios\Data\Catalog\Category;
$categoryData = $searchRawData['hits']['hits'][0]['_source'];
if (!isset($categoryData['links']['webshop'])) {
// this should also never happen, because it is a required property of Category
throw new Exception(sprintf(
"Category for magentoId %s returned data, which is missing property 'links.webshop'",
$magentoId
));
}
return $categoryData['links']['webshop'];
}
}