<?php
namespace App\Controller\API;
use App\Repository\ProductArticleRepository;
use App\Controller\API\ApiBuildController;
use App\Helper\RepositoryHelper;
use App\Service\StaticService;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
use OpenApi\Annotations as OA;
use Doctrine\Persistence\ManagerRegistry;
/**
* Class ApiSelectionController
* @package App\Controller\API
*
*/
class ApiSelectionController extends ApiBuildController
{
private $registry;
public function __construct(ManagerRegistry $registry)
{
$this->registry = $registry;
parent::__construct($registry);
}
/**
* @OA\Tag (name="Получение параметров подбора")
* @Route("/api/select/{selection<wipers|parts>}/{entity<mark|model|category>}", methods={"GET"})
*/
public function select(Request $request, string $entity, string $selection)
{
$result = [];
$params = $request->query->all();
$entityClassName = 'App\Entity\\' . ucfirst($entity);
$routes = [
'wipers' => \App\Entity\SelectionWiper::class,
'parts' => \App\Entity\SelectionPart::class
];
if (isset($routes[$selection]) && class_exists($entityClassName)) {
$repository = $this->registry->getRepository($entityClassName);
$sortedDefault = ['sorted' => ['field' => $entity.'.title']];
$params =$this->normilize(
array_merge($sortedDefault, $params),
$entity
);
$params = $this->normalize_years($params);
$repHelper = new RepositoryHelper($this->registry, $entityClassName);
$result = $repHelper->serialize(
$repository->findOnRequest($params, $routes[$selection]),
'selection/param'
);
}
return new JsonResponse($result);
}
/**
* @OA\Tag (name="Получение параметров подбора (модификация)")
* @Route("/api/select/{selection<wipers|parts>}/{entity<modification|body|years|engine>}", methods={"GET"})
*/
public function selectModification(Request $request, string $entity, string $selection)
{
$result = $array = [];
$params = $request->query->all();
$entityClassName = \App\Entity\Modification::class;
$entityAlias = 'modification';
$routes = [
'wipers' => \App\Entity\SelectionWiper::class,
'parts' => \App\Entity\SelectionPart::class
];
$groupBy = [
'body' => "{$entityAlias}.body",
'engine' => "{$entityAlias}.engine",
'years' => "{$entityAlias}.yearFrom, {$entityAlias}.yearTo"
];
$sortBy = [
'years' => [
'sort' => 'ASC',
'field' => "{$entityAlias}.yearFrom"
],
'default' => [
'field' => "{$entityAlias}.body"
]
];
if (isset($routes[$selection]) && class_exists($entityClassName)) {
$repository = $this->registry->getRepository($entityClassName);
$sortedDefault = isset($sortBy[$entity]) ? ['sorted' => $sortBy[$entity]] : ['sorted' => $sortBy['default']];
$groupByDefault = isset($groupBy[$entity]) ? ['groupBy' => $groupBy[$entity]] : [];
$params =$this->normilize(
array_merge($sortedDefault, $groupByDefault, $params),
$entity
);
$params = $this->normalize_years($params);
$result = $repository->findOnRequest($params, $routes[$selection]);
$repHelper = new RepositoryHelper($this->registry, $entityClassName);
foreach($result as &$item) {
$method = 'get'.ucfirst($entity);
$item = method_exists(__CLASS__, $method) ? $this->$method($repHelper->serialize($item, 'selection/param'), $selection) : $repHelper->serialize($item, 'selection/param');
if ($item) {
$array[] = $item;
}
}
}
return new JsonResponse($array);
}
/**
* @OA\Tag (name="Получение данных подбора")
* @Route("/api/select/{selection<wipers|parts|all>}/data", methods={"GET"})
*/
public function selectData(Request $request, StaticService $staticService, string $selection)
{
$result = [];
$params = $request->query->all();
if (count($params) == 0) {
return new JsonResponse($result, Response::HTTP_BAD_REQUEST);
}
$routes = [
'wipers' => \App\Entity\SelectionWiper::class,
'parts' => \App\Entity\SelectionPart::class
];
if (isset($routes[$selection])) {
$params =$this->normalize_years($params);
$class = $routes[$selection];
$repository = $this->registry->getRepository($class);
$repHelper = new RepositoryHelper($this->registry, $class);
$result = $repHelper->serialize(
$repository->getResponseAPI($repository->findOnRequest($params)),
'selection/data'
);
}
if ($selection === 'all' && $params['search'] && strlen($params['search']) > 2) {
$params['search'] = $this->clearTerm($params['search']);
$class = \App\Entity\ProductOem::class;
$repository = $this->registry->getRepository($class);
// $oemND = $repository->findOnSearchRequest(array_merge($params, ['productArticle' => null]));
$joinProductData = [];
// foreach($oemND as $oem) {
// $joinProductData[$oem->getProduct()->getId()][] = $oem;
// }
$class = \App\Entity\ProductArticle::class;
$repository = $this->registry->getRepository($class);
$repHelper = new RepositoryHelper($this->registry, $class);
$result = $repHelper->serialize(
$repository->getResponseAPI($repository->findOnSearchRequest($params), $joinProductData),
'selection/data'
);
}
$mapArticles = [];
foreach($result as &$item) {
foreach($item['products'] as &$product) {
foreach($product['articles'] as &$article) {
if ($article['title'] !== 'Н/Д') {
$mapArticles[mb_strtolower($article['title'])] = &$article;
}
}
}
}
if (!empty($mapArticles)) {
$articles = array_keys($mapArticles);
$static = $staticService->getImageByArticles($articles, true) ?? [];
foreach($static as $key => $images) {
$article = &$mapArticles[$key];
$article['image'] = array_shift($images);
}
}
return new JsonResponse($result);
}
/**
* @OA\Tag (name="Получение данных подбора по ID артикула")
* @Route("/api/select/{selection<wipers|parts>}/data/{id}", methods={"GET"})
*/
public function selectDataByID(Request $request, StaticService $staticService, string $selection, string $id)
{
$result = [];
$params = $request->query->all();
$routes = [
'wipers' => \App\Entity\SelectionWiper::class,
'parts' => \App\Entity\SelectionPart::class
];
if (isset($routes[$selection]) && $id != null) {
$class = \App\Entity\ProductArticle::class;
$repository = $this->registry->getRepository($class);
$repHelper = new RepositoryHelper($this->registry, $class);
$article = $repository->find($id);
if ($article !== null) {
$product = $article->getProduct();
$product->clearArticlesAndOems();
$product->addProductArticle($article);
$repository = $this->registry->getRepository($routes[$selection]);
$selections = $repository->findByProductArticleId($id);
$applicable = $repHelper->serialize($selections, 'selection/applicable');
$result = $repHelper->serialize($product, 'selection/id');
$result['applicable'] = $applicable;
$result['article'] = [
...$result['article'],
'images' => $staticService->getImageByArticle($result['article']['title'])
];
}
}
return new JsonResponse($result);
}
public function normalize_years(&$params) {
if (isset($params['years']) && $params['years'] !== null) {
$years = ['yearFrom', 'yearTo'];
foreach(explode('|', $params['years']) as $i => $year) {
$params[$years[$i]] = $year ? (int)$year : NULL;
}
unset($params['years']);
}
return $params;
}
public function getYears($item, $selection):array
{
if ($selection === 'parts') {
return [
'id' => $item['yearFrom'].'|'.$item['yearTo'],
'title' => ($item['yearFrom'] ?? 'н/д') .' - '. ($item['yearTo'] ?? 'наст. время')
];
}
return [
'id' => $item['yearFrom'].'|'.$item['yearTo'],
'title' => $item['yearFrom']
];
}
public function getBody($item, $selection): ?array
{
if ($item['body'] === null) return null;
return [
'id' => $item['body'],
'title' => $item['body'],
'modelId' => $item['modelId']
];
}
public function getEngine($item, $selection): ?array
{
if ($item['engine'] === null) return null;
return [
'id' => $item['engine'],
'title' => $item['engine'],
];
}
/**
* remove bad characters
* @param string $term input string
* @return string
*/
public function escapeTerm($term): string
{
return trim(str_replace(array("'", "*", '_', '#', '%23'), '', $term));
}
/**
* clear search term
* @param string $term input string
* @return string
*/
public function clearTerm($term): string
{
$term = $this->escapeTerm($term);
$pattern = "/[^\w,\x2D,А-Я,а-я,ёЁ,_]/u";
$replacement = '';
return preg_replace($pattern, $replacement, $term);
}
}