<?php
namespace WebBundle\Controller;
use Exception;
use FlexApp\Service\LastUrlService;
use Import1CBundle\Helper\v3\BiConst;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use Symfony\Contracts\Translation\TranslatorInterface;
use WebBundle\Enum\CollectionAndFactoryStateEnum;
use WebBundle\Exception\ArticleNotAvailableNowException;
use WebBundle\Filler\MessageFiller;
use WebBundle\Helper\App;
use WebBundle\Helper\LocaleHelper;
use WebBundle\Helper\PathHelper;
use WebBundle\Helper\RedirectHelper;
use WebBundle\Helper\SearchLogHelper;
use WebBundle\Helper\UrlHelper;
use WebBundle\Helper\UserHelper;
use WebBundle\Repository\BuyOrderRepository;
use WebBundle\Repository\CollectionRepository;
use WebBundle\Repository\InteriorRepository;
use WebBundle\Repository\PublicationRepository;
use WebBundle\Service\CollectionService;
use WebBundle\Service\ReviewsService;
use WebBundle\Service\SampleService;
use WebBundle\Service\SliderService;
/**
* Работа слайдера
* коллекция опубликована,
* вызов из коллекции, вызывается 5 слайдов - 0, -2, +2, для крайних уменьшается до 0, игнорируются снятые слайды
* вызов из би - вызывается 5 слайдов аналогично, снятые игнорируются
* прямой вызов - вызвается 5 слайдов, снятые игнорируются
* прямой вызов снятого - вызвается 1 слайд
* при перелистываении подгружается крайний +-1 слайд
*
* коллекция неопубликована - слайдер заблокирован для всех случаев
*
* коллекция снята -
* только прямой вызов по одному слайду
*
* коллекция импортирована
* вызвается 5 слайдов аналогично
* прямой вызов - 5 слайдов
*
* Коллекция на проверке
* вызывается 5 слайдов аналогично
* collection controller.
*/
class SliderController extends ExtendedController
{
/** @required */
public BuyOrderRepository $buyOrderRepository;
/** @required */
public PublicationRepository $publicationRepository;
/** @required */
public CollectionRepository $collectionRepository;
/** @required */
public InteriorRepository $interiorRepository;
/** @required */
public CollectionService $collectionService;
/** @required */
public ReviewsService $reviewsService;
/** @required */
public SampleService $sampleService;
/** @required */
public SliderService $sliderService;
/** @required */
public MessageFiller $messageFiller;
/** @required */
public LastUrlService $lastUrlService;
private AuthorizationChecker $authorizationChecker;
private TranslatorInterface $translator;
public function __construct(
AuthorizationChecker $authorizationChecker,
TranslatorInterface $translator
) {
parent::__construct();
$this->authorizationChecker = $authorizationChecker;
$this->translator = $translator;
}
/**
* @param Request $request
* @param $factoryUrl
* @param $collectionUrl
* @param $type
* @param $elementId
* @return Response
* @throws Exception|\Doctrine\DBAL\Driver\Exception
*/
public function indexAction(Request $request, $factoryUrl, $collectionUrl, $type, $elementId)
{
// проверка переноса фабрики
if ($iNeedRedirect = RedirectHelper::checkRedirect($factoryUrl, $collectionUrl, $type, $elementId)) {
return $this->redirect(
$this->generateUrl(
'app_collection',
$iNeedRedirect->getArrayForRedirect()
)
);
}
$token = UserHelper::getInstance()->getToken();
$collection = $this->collectionRepository->getSlideCollection($factoryUrl, $collectionUrl);
// проверка на сменный URL коллекции
if (!$collection) {
$redirect = $this->lastUrlService->getSliderRedirectUrl($collectionUrl, $factoryUrl, $type, $elementId);
if ($redirect) {
return new RedirectResponse($redirect);
}
}
if (!$collection) {
throw $this->createNotFoundException('Element not found');
}
$isCollectionStatus = in_array(
$collection['status'],
[CollectionAndFactoryStateEnum::STATE_DISCONTINUED, CollectionAndFactoryStateEnum::STATE_WORK_CONTINUED]
);
// Закрываем доступ для еще не опубликованных коллекций
if (
!in_array(
$collection['status'],
[CollectionAndFactoryStateEnum::STATE_PUBLISHED, CollectionAndFactoryStateEnum::STATE_DISCONTINUED, CollectionAndFactoryStateEnum::STATE_WORK_CONTINUED]
)
&& !$this->authorizationChecker->isGranted('ROLE_ADMIN')
) {
throw $this->createNotFoundException('Slide not found');
}
$msg = $this->collectionService->getAlertMessageIfCollectionInDiscontinuedState($collection);
if ($msg !== null) {
return $this->crushBecauseItsNotAvailableNow($msg, $elementId, $type, $request);
}
$isBiFreezed = $request->get('is_freezed');
$isFactoryStatus = in_array(
$collection['factory']['status'],
[CollectionAndFactoryStateEnum::STATE_DISCONTINUED, CollectionAndFactoryStateEnum::STATE_WORK_CONTINUED]
);
$isFreezed = ($isBiFreezed !== null) ? (bool) $isBiFreezed : $isCollectionStatus || $isFactoryStatus;
$suspended = $isCollectionStatus || $isFactoryStatus;
$pathData = [
'factoryUrl' => $collection['factory']['url'],
'collectionUrl' => $collection['url'],
'file' => '%img%',
];
try {
$data = $this->sliderService->getData($request, $token, $type, $collection, $elementId);
} catch (ArticleNotAvailableNowException $_) {
$url = $this->generateUrl('app_catalog', ['key' => $collection['url']]);
$msg = $this->messageFiller->getMessageForDiscontinuedArticle($collection['name'], $url);
return $this->crushBecauseItsNotAvailableNow($msg, $elementId, $type, $request);
}
if (!empty($data['redirect'])) {
return new RedirectResponse($data['redirect'], 301);
}
if (
(count($data['elements']) === 0 && $type !== 'i')
|| $data['elementId'] === null
) {
throw new NotFoundHttpException('The element is not found or it has the column "file" is null');
}
$countryUrl = $this->sliderService->getCountryUrl($collection);
// Специальная ссылка на блог
$blog = $this->publicationRepository->find(PublicationController::BLOG_ABOUT_SAMPLE_ID);
$qr = $this->sampleService->getQr($request, $type, $data, $collection, $isFreezed);
$reviews = $this->reviewsService->getReviewByCollection($collection['code']);
$output = [
'windowSizes' => json_decode($request->cookies->get('windowSizes', '{}'), true),
'filters' => $this->getGoogleRefererInfo(),
'qr' => $qr,
'msg' => null,
'elements' => $data['elements'],
'elementsCount' => $data['elementsCount'],
'elementId' => $data['elementId'],
'number' => $data['numberElement'],
'type' => $type,
'suspended' => $suspended,
'dataNoRegular' => $collection['factory']['suspended'],
'buyOrderArticles' => $this->buyOrderRepository->getInfoBuyOrderArticle($token),
'userCountry' => App::getCurCountry(),
'userLocale' => App::getCurLocale(),
'currency' => LocaleHelper::getCurrency(LocaleHelper::getCur()),
'measureGb' => LocaleHelper::measureGb(),
'vatPercent' => LocaleHelper::includeVATAlways(),
'urls' => [
'settings' => App::generateUrl('app_article_settings', ['id' => 0]),
'collection' => App::generateUrl(
'app_collection',
['factoryUrl' => '%factory%', 'collectionUrl' => '%collection%']
),
'factory' => App::generateUrl('app_catalog', ['key' => '%factory%']),
'country' => $countryUrl,
'ideas' => App::generateUrl('app_ideas_list', ['id' => '%id%']),
'pathImg' => [
'item' => PathHelper::pathGenerate('article', $pathData),
'interior' => PathHelper::pathGenerate('interior', $pathData),
],
'fastDeliverySamplesUrl' => UrlHelper::genUrlBlogSingle($blog),
'mainPic' => PathHelper::pathGenerate('main', $collection),
],
'stateNotTime' => CollectionAndFactoryStateEnum::STATE_NOT_TIME,
'statePublished' => CollectionAndFactoryStateEnum::STATE_PUBLISHED,
'stateDiscontinued' => CollectionAndFactoryStateEnum::STATE_DISCONTINUED,
'stateProcessing' => CollectionAndFactoryStateEnum::STATE_PROCESSING,
'isWithoutVATPrice' => LocaleHelper::isWithoutVATPrice(10) !== false,
'isFreezed' => $isFreezed,
'closed' => ($collection['status'] == CollectionAndFactoryStateEnum::STATE_DISCONTINUED
? $this->translator->trans('collection_unavailable_freezed_desc')
: ($collection['status'] == CollectionAndFactoryStateEnum::STATE_PROCESSING
? $this->translator->trans('collection_unavailable')
: ''
)),
'closedHelp' => $collection['status'] == CollectionAndFactoryStateEnum::STATE_PROCESSING
? $this->translator->trans('collection_unavailable_manufacture_desc')
: '',
'trans' => [
'orderHelp' => $this->translator->trans('buyOrder.help'),
'collectionCeilToPallet' => $this->translator->trans('collection_ceil_to_pallet'),
'popupAutoChangeCountArts' => $this->translator->trans('popup_auto_change_count_arts'),
'collectionAtentionPallet' => $this->translator->trans('collection_atention_pallet'),
'articleTypeSample' => $this->translator->trans('article.type.sample'),
'collection_Article' => $this->translator->trans('collection_article'),
'collection_Interior' => $this->translator->trans('collection_interior'),
'collectionName' => $this->translator->trans('collection_name'),
'catalogFactory' => $this->translator->trans('catalog_factory'),
'articleCharacteristics' => $this->translator->trans('article_characteristics'),
'articleItemFormats' => $this->translator->trans('article_item_formats'),
'itemDifferentPatterns' => $this->translator->trans('item_different_patterns'),
'itemVariationsOfGraphics' => $this->translator->trans('item_variations_of_graphics'),
'vatLabel' => $this->translator->trans('vat.label'),
'vatIncluded' => $this->translator->trans('vat.included'),
'catalogPrice' => $this->translator->trans('catalog_price'),
'articleDiscountinued' => $this->translator->trans('article.discountinued'),
'collectionBack' => $this->translator->trans('collection_back'),
'commentAddQuestion' => $this->translator->trans('comment_add_question'),
'articleInStock' => $this->translator->trans('article_in_stock'),
'item' => [
'collection' => $this->translator->trans('collection_name'),
'factory' => $this->translator->trans('catalog_factory'),
'characteristics' => $this->translator->trans('article_characteristics'),
'header' => $this->translator->trans('collection_articles_d'),
'formats' => $this->translator->trans('article_item_formats'),
'cm' => $this->translator->trans('left_menu_cm'),
'translated_by_google' => $this->translator->trans('translated_by_google'),
'show_translate' => $this->translator->trans('show_translate'),
'show_original' => $this->translator->trans('show_original'),
'all_specifications' => $this->translator->trans('all_specifications'),
'inch' => '″',
'diameter' => $this->translator->trans('article_item_diameter'),
'pcs' => $this->translator->trans('measure_unit'),
'pcsPlural' => $this->translator->trans('measure_units'),
'set' => $this->translator->trans('measure_set'),
'sets' => $this->translator->trans('measure_sets'),
'settings' => $this->translator->trans('collection_marks'),
'someSettings' => $this->translator->trans('article_characteristics'),
'allSettings' => $this->translator->trans('all'),
'price' => $this->translator->trans('catalog_price'),
'vat' => [
'label' => $this->translator->trans('vat.label'),
'included' => $this->translator->trans('vat.included'),
'excluded' => $this->translator->trans('vat.excluded'),
],
'info' => $this->translator->trans('article_item_more_info'),
'infoLess' => $this->translator->trans('article_item_less_info'),
'order' => [
'help' => $this->translator->trans('buyOrder.help'),
'ceilToPallet' => $this->translator->trans('collection_ceil_to_pallet'),
'atentionPallet' => $this->translator->trans('collection_atention_pallet'),
'popupAutoChangeCountArts' => $this->translator->trans('popup_auto_change_count_arts'),
],
'up' => $this->translator->trans('article.price.up'),
'down' => $this->translator->trans('article.price.down'),
'readMore' => $this->translator->trans('read_more'),
'titleAddedArticle' => $this->translator->trans('buyOrder.titleAddedArticle'),
'addIntoOrder' => $this->translator->trans('buy_order.add_into_order'),
'headerOrderAdd' => $this->translator->trans('header_order_add'),
'draft' => $this->translator->trans('order.status.draft'),
'typeMain' => $this->translator->trans('article.type.main'),
'typeSample' => $this->translator->trans('article.type.sample'),
'sampleText' => $this->translator->trans('article.type.sampleText'),
'typeCompare' => $this->translator->trans('article.type.compare'),
'compareText' => $this->translator->trans('article.type.compareText'),
'type3d' => $this->translator->trans('article.type.3d'),
'text3d' => $this->translator->trans('article.type.3dText'),
'articleOrderOver' => $this->translator->trans('article.order.over'),
'articlePricePerPallet' => $this->translator->trans('article.price.perPallet'),
'articlePriceNoLessPallet' => $this->translator->trans('article.price.noLessPallet'),
'articlePricePalleteFrom' => $this->translator->trans('article.pricePallete.from'),
'articlePriceFrom' => $this->translator->trans('article.price.from'),
'articlePricePalleteUnder' => $this->translator->trans('article.pricePallete.under'),
'articlePriceFromTo' => $this->translator->trans('article.price.from_to'),
'articleOrderMultiplies' => $this->translator->trans('article.order.multiplies'),
'highResolutionImageDownload' => $this->translator->trans('image_download_high_resolution'),
'boxArticleSingle' => $this->translator->trans('box_article_single'),
'boxArticlePlural' => $this->translator->trans('box_article_plural'),
'articleNoImgTitle' => $this->translator->trans('article.no_img'),
'collectionAddOrder' => $this->translator->trans('collection_add_order'),
'tempNoUKShippingMsg' => $this->translator->trans('msg.uk'),
'discountinued' => $this->translator->trans('article.discountinued'),
'tempUnavailable' => $this->translator->trans('article.temp_unavailable'),
],
'sample' => [
'folder' => $this->translator->trans('sample.folder.text'),
'original' => $this->translator->trans('sample.original.text'),
'piece' => $this->translator->trans('sample.piece.text'),
'title' => $this->translator->trans('samplePopup.title'),
'noMoreShow' => $this->translator->trans('samplePopup.noMoreShow'),
'withDecl' => $this->translator->trans('article.type.sampleWithDecl'),
'alreadyAdded' => $this->translator->trans('sample_already_added.header'),
'fitsForItems' => $this->translator->trans('fits_for_items'),
],
'reviews' => [
'heading' => $this->translator->trans('collection_customer_reviews'),
'validUser' => $this->translator->trans('product_validUser'),
'reply' => $this->translator->trans('reply_comment'),
'edit' => $this->translator->trans('edit'),
'save' => $this->translator->trans('save'),
'cancel' => $this->translator->trans('cancel'),
'stars' => $this->translator->trans('reviews.stars.many'),
'pluralForms' => $this->translator->trans('review.plural_forms'),
],
'box' => $this->translator->trans('measure_box'),
'boxes' => $this->translator->trans('boxes'),
'collectionNotRegular' => $this->translator->trans('collection.notRegular'),
'collectionBy' => $this->translator->trans('collection_by'),
'ideaDelInteriorMsg' => $this->translator->trans('idea_del_interior_msg'),
'ideaYes' => $this->translator->trans('idea_yes'),
'ideaNo' => $this->translator->trans('idea_no'),
'ideaMsgAdded' => $this->translator->trans('idea_msg_added'),
'ideaMsgNormal' => $this->translator->trans('idea_msg_normal'),
'ideaMsgNormalMany' => $this->translator->trans('idea_msg_normal_many'),
'ideaMsgNormalZero' => $this->translator->trans('idea_msg_normal_zero'),
'articleItemDiameter' => $this->translator->trans('article_item_diameter'),
'leftMenuCm' => $this->translator->trans('left_menu_cm'),
'leftMenuInch' => '″',
'sampleFolderText' => $this->translator->trans('sample.folder.text'),
'sampleOriginalText' => $this->translator->trans('sample.original.text'),
'samplePieceText' => $this->translator->trans('sample.piece.text'),
'unavailableFreezedDescArticle' => $this->translator->trans('collection_unavailable_freezed_desc_article'),
'discountinued' => $this->translator->trans('article.discountinued'),
'articleInInterior' => $this->translator->trans('article_in_interior'),
'factoryCountry' => $this->translator->trans($collection['factory']['country']['alias']),
'collectionIdeasShort' => $this->translator->trans('collection_ideas_short'),
],
'reviews' => [
'data' => $reviews,
'urls' => [
'preDataCollectionReviewsUrl' => App::generateUrl(
'pre_data_collection_reviews',
['id' => $collection['id']]
),
'collectionReviewsUrl' => App::generateUrl('collection_reviews', ['id' => $collection['id']]),
],
],
];
$imagePreload = null;
if (!empty($output['elements'][$output['elementId']]['pathImg'])) {
$imagePreload = $output['elements'][$output['elementId']]['pathImg'];
}
SearchLogHelper::save([
'url' => $request->getUri(),
'title' => $data['elements'][$data['elementId']]['title'] ?? 'empty interior',
]);
if ($request->get('only-slider')) {
return new JsonResponse(['slider' => $output]);
} else {
$art = $data['elements'][$data['elementId']];
if ($type == 'i') {
$art = !empty($art['articles'][0]) ? $art['articles'][0] : null;
}
$isShowReview = $collection['status'] == BiConst::STATE_PUBLISHED && LocaleHelper::getPrMin($collection) > 0;
return $this->renderReact('@Web/Slider/index.html.twig', [
'imagePreload' => $imagePreload,
'metaData' => [
'title' => $data['elements'][$data['elementId']]['title'],
'description' => $data['elements'][$data['elementId']]['description'],
'keyword' => '',
],
//для динамического ремаркетинга
'ecommProdid' => $data['elementId'],
'ecommTotalvalue' => $art ? LocaleHelper::getPrice($art) : 0,
'initialState' => ['slider' => $output, 'reviews' => $isShowReview ? $reviews : []],
]);
}
}
/**
* @param Request $request
* @param string $factoryUrl
* @param string $collectionUrl
* @param string $type
* @param string|int $elementId
* @param ?string $load
* @return Response
* @throws Exception|\Doctrine\DBAL\Driver\Exception
*/
public function slideAction(
Request $request,
string $factoryUrl,
string $collectionUrl,
string $type,
$elementId,
?string $load = 'all'
) {
$token = UserHelper::getInstance()->getToken();
$collection = $this->collectionRepository->getSlideCollection($factoryUrl, $collectionUrl);
if (!$collection) {
throw $this->createNotFoundException('The collection is not found');
}
$data = $this->sliderService->getData($request, $token, $type, $collection, $elementId, $load);
return new JsonResponse(['elements' => $data['elements']]);
}
private function getGoogleRefererInfo(): bool
{
if (
stripos($_SERVER['HTTP_REFERER'] ?? '', 'google.') !== false
&& stripos($_SERVER['HTTP_REFERER'] ?? '', 'mail.google.') === false
) {
return true;
}
if (
!empty($_GET['utm_source'])
) {
return true;
}
// https://te2.remote.team/discus/DA0E211E-CD52-A435-805A-0039E39A2954
if (stripos($_SERVER['HTTP_REFERER'] ?? '', 'googleadservices.') !== false) {
return true;
}
// https://te2.remote.team/discus/D058F322-78AA-AEBE-9D88-B2B9B077677C
if (empty($_SERVER['HTTP_REFERER'])) {
return true;
}
return false;
}
/**
* @param array $msg
* @param $elementId
* @param $type
* @param Request $request
* @return JsonResponse|Response
* @throws Exception
*/
private function crushBecauseItsNotAvailableNow(array $msg, ?string $elementId, ?string $type, Request $request)
{
$slider = ['msg' => $msg, 'elementId' => $elementId, 'elements' => [$elementId => ['artImgSrc' => null]], 'type' => $type];
if ($request->get('only-slider')) {
return new JsonResponse(['slider' => $slider]);
}
$state = [
'metaData' => [
'title' => $msg['header'],
'description' => $msg['body'],
'keyword' => '',
],
'initialState' => ['slider' => $slider],
];
return $this->renderReact('@Web/Slider/index.html.twig', $state);
}
}