src/WebBundle/Controller/IdeaController.php line 90

Open in your IDE?
  1. <?php
  2. namespace WebBundle\Controller;
  3. use DateTime;
  4. use Doctrine\ORM\OptimisticLockException;
  5. use Doctrine\ORM\ORMException;
  6. use Exception;
  7. use FlexApp\Service\RedisCachePool;
  8. use Monolog\Logger;
  9. use Symfony\Component\HttpFoundation\JsonResponse;
  10. use Symfony\Component\HttpFoundation\Request;
  11. use Symfony\Component\HttpFoundation\Response;
  12. use WebBundle\Entity\Collection;
  13. use WebBundle\Entity\Idea;
  14. use WebBundle\Entity\Interior;
  15. use WebBundle\Entity\InteriorHistory;
  16. use WebBundle\Helper\App;
  17. use WebBundle\Helper\CookieHelper;
  18. use WebBundle\Helper\ResponseApiHelper;
  19. use WebBundle\Helper\TwigTe;
  20. use WebBundle\Helper\UserHelper;
  21. use WebBundle\Repository\CollectionRepository;
  22. use WebBundle\Repository\FilterRepository;
  23. use WebBundle\Repository\IdeaRepository;
  24. use WebBundle\Repository\IdeasShareRepository;
  25. use WebBundle\Repository\InteriorHistoryRepository;
  26. use WebBundle\Repository\InteriorRepository;
  27. use WebBundle\Service\IdeaService;
  28. /**
  29.  * Class IdeaController
  30.  * @package WebBundle\Controller
  31.  */
  32. class IdeaController extends ExtendedController
  33. {
  34.     const COUNT_IDEAS_ON_POPUP 6;
  35.     const HEIGHT_STRING 60;
  36.     private array $message = [
  37.         'getTokenByKey' => 'Ключ авторизации не правильный, либо вышел срок его действия',
  38.         'deleteIdea' => 'Не найдены соответствующий проект идей для удаления',
  39.         'editIdea' => 'Не найдены соответствующий проект идей для редактирования',
  40.         'copyIdea' => 'Попытка скопировать не существующий проект',
  41.         'copySelfIdea' => 'Попытка скопировать свой проект',
  42.         'noArrayInteriorsId' => 'Отсутствует массив идентификаторов интерьеров',
  43.         'noArrayInteriorsObj' => 'Не найдено интерьеров для слияния',
  44.         'noInterior' => 'Не найдено интерьера с данным идентификатором',
  45.         'noIdea' => 'Не найдено проекта идей с данным идентификатором',
  46.     ];
  47.     protected Logger $logger;
  48.     /** @required */
  49.     public CollectionRepository $collectionRepository;
  50.     /** @required */
  51.     public InteriorRepository $interiorRepository;
  52.     /** @required */
  53.     public InteriorHistoryRepository $interiorHistoryRepository;
  54.     private IdeaRepository $ideaRepository;
  55.     protected string $token;
  56.     /**
  57.      * IdeaController constructor.
  58.      * @param Logger $logger
  59.      * @param IdeaRepository $repo
  60.      * @throws Exception
  61.      */
  62.     public function __construct(
  63.         Logger $logger,
  64.         IdeaRepository $repo
  65.     ) {
  66.         parent::__construct();
  67.         $this->logger $logger;
  68.         $this->ideaRepository $repo;
  69.         $this->token UserHelper::getInstance()->getToken();
  70.     }
  71.     /**
  72.      * Страница проектов идей
  73.      * @param Request $request
  74.      * @return Response
  75.      * @throws OptimisticLockException
  76.      * @throws Exception
  77.      */
  78.     public function indexAction(Request $request): Response
  79.     {
  80.         /** @var Idea $idea */
  81.         $ideas $this->ideaRepository->getIdeasByToken($this->token);
  82. //        App::dumpExit($ideas);
  83.         $noR = (null !== $request->query->get('noR')) ? $request->query->get('noR') : null;
  84.         if (count($ideas) == && empty($noR)) {
  85.             /** @var Idea $idea */
  86.             $idea $ideas[0];
  87.             return $this->redirect(TwigTe::ideaUrl($idea));
  88.         }
  89.         $lastUpdate null;
  90.         $list = [];
  91.         /** @var Idea $idea */
  92.         foreach ($ideas as $idea) {
  93.             if (!$lastUpdate) {
  94.                 $lastUpdate $idea->getUpdateDate() ?: $idea->getCreateDate();
  95.             }
  96.             $interiorSrc = empty($idea->getInteriors()[0]) ? ' no-img' $idea->getInteriors()[0]->getWebPathPreview();
  97.             $interiorAlt = empty($idea->getInteriors()[0]) ? '' $idea->getInteriors()[0]->getName();
  98.             $list[] = [
  99.                 'id' => $idea->getId(),
  100.                 'url' => TwigTe::ideaUrl($idea),
  101.                 'interiors' => $idea->getInteriors()->count(),
  102.                 'src' => $interiorSrc,
  103.                 'name' => $idea->getName(),
  104.                 'alt' => $interiorAlt
  105.             ];
  106.         }
  107.         return $this->renderReact(
  108.             '@Web/Idea/index.html.twig',
  109.             [
  110.                 'title' => App::trans('idea_header_list'),
  111.                 'description' => App::trans('ideas_description'),
  112.                 'initialState' => [
  113.                     'ideas' => [
  114.                         'list' => $list,
  115.                         'userLocale' => App::getCurLocale(),
  116.                         'lastUpdate' => $lastUpdate,
  117.                         'paths' => $this->paths(),
  118.                         'trans' => $this->trans()
  119.                     ]
  120.                 ]
  121.             ]
  122.         );
  123.     }
  124.     /**
  125.      * Всплывающее окно проектов идей
  126.      * @param Request $request
  127.      * @return Response
  128.      * @throws Exception
  129.      */
  130.     public function lastIdeasAction(Request $request): Response
  131.     {
  132.         $targetHeight $request->query->get('targetHeight');
  133.         $countString = ($targetHeight) ? floor($targetHeight self::HEIGHT_STRING) : self::COUNT_IDEAS_ON_POPUP;
  134.         $token UserHelper::getInstance()->getToken();
  135.         /** @var Idea $idea */
  136.         $ideas $this->ideaRepository->getIdeasByToken($token);
  137.         return $this->render(
  138.             '@Web/Idea/last-ideas.html.twig',
  139.             [
  140.                 'ideas' => $ideas,
  141.                 'countString' => $countString,
  142.             ]
  143.         );
  144.     }
  145.     /**
  146.      * Страница идеи
  147.      * @param string $url
  148.      * @param ?string $name
  149.      * @return Response
  150.      * @throws Exception
  151.      */
  152.     public function showAction(string $url, ?string $name null): Response
  153.     {
  154.         $idea $this->ideaRepository->getIdeaByUrl(str_replace([' ''%20'], '_'urldecode($url)), urldecode($name));
  155.         if (!$idea) {
  156.             $this->logger->error('не найдена идея: (' json_encode($idea) . ') по параметрам url:(' .
  157.                 str_replace([' ''%20'], '_'urldecode($url)) . ') name:(' urldecode($name) . ')');
  158.             throw $this->createNotFoundException($this->message['noIdea']);
  159.         } else {
  160.             if ($idea->getUser() == null) {
  161.                 $user App::getCurUser();
  162.                 if ($user) {
  163.                     $idea->setUser($user);
  164.                 }
  165.             }
  166.             $sort CookieHelper::get('ideaSort'3);
  167.             /** @var InteriorRepository $interiorRepo */
  168.             $interiorRepo App::getRepository('WebBundle:Interior');
  169.             $interiors $interiorRepo->getInteriorsByIdeaSort($idea->getId(), $sort);
  170.             /** @var IdeasShareRepository $ideasShareRepo */
  171.             $ideasShareRepo App::getRepository('WebBundle:IdeasShare');
  172.             $clickIdeaShareToSocials $ideasShareRepo->getClickIdeaShareToSocials($idea->getId());
  173.             /** @var FilterRepository $filterRepo */
  174.             $filterRepo App::getRepository('WebBundle:FilterEntity');
  175.             $listSort $filterRepo->getSortListCataloge();
  176.             $sortVariants = [];
  177.             if (!empty($listSort[1])) {
  178.                 $sortVariants[1] = $listSort[1];
  179.             }
  180.             if (!empty($listSort[3])) {
  181.                 $sortVariants[3] = $listSort[3];
  182.             }
  183.             if (!empty($listSort[4])) {
  184.                 $sortVariants[4] = $listSort[4];
  185.             }
  186.             $output = [
  187.                 'idea' => $idea,
  188.                 'sort' => $sort,
  189.                 'sortList' => $sortVariants,
  190.                 'interiors' => $interiors,
  191.                 'clickIdeaShareToSocialsItem' => $clickIdeaShareToSocials,
  192.                 'master' => UserHelper::getInstance()->getToken() == $idea->getToken(),
  193.             ];
  194.             return $this->render(
  195.                 '@Web/Idea/show.html.twig',
  196.                 $output
  197.             );
  198.             // для ReactJs
  199.             // return $this->render(
  200.             //     '@Web/Idea/show.html.twig',
  201.             //     [
  202.             //         'title' => $idea->getName(),
  203.             //         'initialState' => $output
  204.             //     ]
  205.             // );
  206.         }
  207.     }
  208.     /**
  209.      * Страница сортировки идеи
  210.      * @param int $id
  211.      * @param ?int $sort
  212.      * @return Response
  213.      * @throws Exception
  214.      */
  215.     public function showSortAction(int $id, ?int $sort 3): Response
  216.     {
  217.         /** @var InteriorRepository $interiorRepo */
  218.         $interiorRepo App::getRepository('WebBundle:Interior');
  219.         $interiors $interiorRepo->getInteriorsByIdeaSort($id$sort);
  220.         // сохраняем выбранный вариант сортировки идей
  221.         CookieHelper::set('ideaSort'$sort);
  222.         $owner false;
  223.         if ($this->ideaRepository->checkMasterIdea($id)) {
  224.             $owner true;
  225.         }
  226.         return $this->render(
  227.             '@Web/Idea/idea_elements.html.twig',
  228.             [
  229.                 'ideaId' => $id,
  230.                 'interiors' => $interiors,
  231.                 'owner' => $owner
  232.             ]
  233.         );
  234.     }
  235.     /**
  236.      * Страница списка идей
  237.      *
  238.      * @param int $id
  239.      * @param ?int $oldIdeaId Старый id идеи, (null - по умолчанию)
  240.      * @param ?string $type Тип добавление (add - по умолчанию) или передвижение (add | move)
  241.      * @return Response
  242.      * @throws OptimisticLockException
  243.      * @throws Exception
  244.      */
  245.     public function listAction(int $id, ?int $oldIdeaId null, ?string $type 'add')
  246.     {
  247.         $token UserHelper::getInstance()->getToken();
  248.         /** @var Idea $idea */
  249.         $ideas $this->ideaRepository->getIdeasByToken($token);
  250.         $em App::em();
  251.         // если ещё нет проекта, то создаем
  252.         if (count($ideas) == 0) {
  253.             $idea = new Idea();
  254.             $idea->setCreateDate(new DateTime());
  255.             $idea->setUpdateDate(new DateTime());
  256.             $idea->setName(App::trans('idea_new_project'));
  257.             $idea->setToken($token);
  258.             $em->persist($idea);
  259.             $em->flush();
  260.             $ideas[] = $idea;
  261.         }
  262.         if (count($ideas) == 1) {
  263.             if ($type == 'move') {
  264.                 return new JsonResponse(
  265.                     [
  266.                         'html' => $this->render(
  267.                             '@Web/Idea/message.html.twig',
  268.                             [
  269.                                 'showMessage' => !$this->getUser(),
  270.                                 'handler' => $type,
  271.                             ]
  272.                         )->getContent(),
  273.                     ]
  274.                 );
  275.             } else {
  276.                 /** @var Idea $idea */
  277.                 $idea $ideas[0];
  278.                 return $this->redirect(
  279.                     $this->generateUrl(
  280.                         'app_idea_interior_change',
  281.                         [
  282.                             'interiorId' => $id,
  283.                             'ideaId' => $idea->getId(),
  284.                             'type' => $type
  285.                         ]
  286.                     )
  287.                 );
  288.             }
  289.         } else {
  290.             $interior App::getRepository('WebBundle:Interior')->findOneBy(['id' => $id]);
  291.             $active = [];
  292.             /** @var Idea $idea */
  293.             foreach ($ideas as $idea) {
  294.                 if ($idea->getInteriors()->contains($interior)) {
  295.                     $active[$idea->getId()] = true;
  296.                 }
  297.             }
  298.             return new JsonResponse(
  299.                 [
  300.                     'html' => $this->render(
  301.                         '@Web/Idea/list.html.twig',
  302.                         [
  303.                             'interiorId' => $id,
  304.                             'ideas' => $ideas,
  305.                             'showMessage' => !$this->getUser(),
  306.                             'active' => $active,
  307.                             'handler' => $type,
  308.                             'oldIdeaId' => $oldIdeaId,
  309.                         ]
  310.                     )->getContent(),
  311.                 ]
  312.             );
  313.         }
  314.     }
  315.     /**
  316.      * Создание проекта идей
  317.      * @param string $name Название проекта
  318.      * @return Response
  319.      * @throws OptimisticLockException
  320.      * @throws Exception
  321.      */
  322.     public function createAction(?string $name)
  323.     {
  324.         $res = new ResponseApiHelper();
  325.         $token UserHelper::getInstance()->getToken();
  326.         if ($res->isValid()) {
  327.             $name IdeaService::getNameIdea($token$name ?? 'null');
  328.             $idea = new Idea();
  329.             $user App::getCurUser();
  330.             if ($user) {
  331.                 $idea->setUser($user);
  332.             }
  333.             $idea->setToken($token);
  334.             $idea->setName($name);
  335.             $idea->setProcess(1);
  336.             $idea->setCreateDate(new DateTime());
  337.             $idea->setUpdateDate(new DateTime());
  338.             $em App::em();
  339.             $em->persist($idea);
  340.             $em->flush();
  341.             $interiorSrc = empty($idea->getInteriors()[0]) ? ' no-img' $idea->getInteriors()[0]->getWebPathPreview();
  342.             $interiorAlt = empty($idea->getInteriors()[0]) ? '' $idea->getInteriors()[0]->getName();
  343.             $res->setResponse('res', [
  344.                 'state' => 'created',
  345.                 'idea' => [
  346.                     'id' => $idea->getId(),
  347.                     'url' => TwigTe::ideaUrl($idea),
  348.                     'interiors' => $idea->getInteriors()->count(),
  349.                     'src' => $interiorSrc,
  350.                     'name' => $idea->getName(),
  351.                     'alt' => $interiorAlt,
  352.                     'notification' => App::trans(
  353.                         'idea.create.msg',
  354.                         App::getCurLocale(),
  355.                         ['%name%' => '<b>' $idea->getName() . '</b>']
  356.                     )
  357.                 ]
  358.             ]);
  359.         }
  360.         return new JsonResponse($res->result());
  361.     }
  362.     /**
  363.      * Редактирование проекта идей
  364.      * @param int $id - код проекта идеи
  365.      * @param string $name - название проекта
  366.      * @return Response
  367.      * @throws OptimisticLockException
  368.      * @throws Exception
  369.      */
  370.     public function editAction(int $idstring $name)
  371.     {
  372.         /** @var ResponseApiHelper $response */
  373.         $res = new ResponseApiHelper();
  374.         $token UserHelper::getInstance()->getToken();
  375.         if ($res->isValid()) {
  376.             $idea App::getContainer()->get('app.repo.idea')->findOneBy(
  377.                 ['token' => $token'id' => $id]
  378.             );
  379.             if (!$idea) {
  380.                 $res->validate('editIdea'null'empty'$this->message['editIdea']);
  381.             } else {
  382.                 $name str_replace('/'''$name);
  383.                 $name IdeaService::getNameIdea($token$name$idea->getId());
  384.                 $idea->setToken($token);
  385.                 $idea->setName($name);
  386.                 $idea->setCreateDate(new DateTime());
  387.                 $idea->setUpdateDate(new DateTime());
  388.                 $em App::em();
  389.                 $em->persist($idea);
  390.                 $em->flush();
  391.                 $result = [
  392.                     'state' => 'updated',
  393.                     'idea' => [
  394.                         'id' => $idea->getId(),
  395.                         'name' => $idea->getName(),
  396.                         'url' => TwigTe::ideaUrl($idea)
  397.                     ],
  398.                 ];
  399.                 $res->setResponse('res'$result);
  400.             }
  401.         }
  402.         return new JsonResponse($res->result());
  403.     }
  404.     /**
  405.      * Удаление проектов идей
  406.      * @param string $id - идентификаторы проектов идей разделённые |
  407.      * @return mixed
  408.      * @throws OptimisticLockException
  409.      * @throws Exception
  410.      */
  411.     public function deleteAction(string $id): JsonResponse
  412.     {
  413.         /** @var ResponseApiHelper $response */
  414.         $res = new ResponseApiHelper();
  415.         $token UserHelper::getInstance()->getToken();
  416.         if ($res->isValid()) {
  417.             $ideas App::getContainer()->get('app.repo.idea')->findBy(
  418.                 ['token' => $token'id' => explode('|'$id)]
  419.             );
  420.             if (!$ideas) {
  421.                 $res->validate('deleteIdea'null'empty'$this->message['deleteIdea']);
  422.             } else {
  423.                 $em App::em();
  424.                 $result = ['action' => 'ok'];
  425.                 /** @var Idea $idea */
  426.                 foreach ($ideas as $idea) {
  427.                     /** @var Interior $interior */
  428.                     foreach ($idea->getInteriors() as $interior) {
  429.                         $result['c_rating'][$interior->getCollection()->getId()] = (int)($interior->getCollection()->getRating() - 1);
  430.                         $result['i_rating'][$interior->getId()] = (int)($interior->getIdeas()->count() - 1);
  431.                     }
  432.                     $em->remove($idea);
  433.                     $em->flush();
  434.                 }
  435.                 /** @var IdeaRepository $repoIdea */
  436.                 $repoIdea App::getContainer()->get('app.repo.idea');
  437.                 $result['all'] = $repoIdea->countByToken($token);
  438.                 $res->setResponse('result'$result);
  439.             }
  440.         }
  441.         return new JsonResponse($res->result());
  442.     }
  443.     /**
  444.      * Добавление удаление интерьера из идей
  445.      * @param int $interiorId - идентификаторы интерьера
  446.      * @param int $ideaId - идентификатор проекта идеи
  447.      * @param ?string $type
  448.      * @return mixed
  449.      * @throws Exception
  450.      */
  451.     public function changeIdeaInteriorAction(int $interiorIdint $ideaId, ?string $type null): JsonResponse
  452.     {
  453.         /** @var ResponseApiHelper $response */
  454.         $res = new ResponseApiHelper();
  455.         $token UserHelper::getInstance()->getToken();
  456.         $interior $this->interiorRepository->find($interiorId);
  457.         if (!$interior) {
  458.             $res->validate('noInterior'null'empty'$this->message['noInterior']);
  459.         }
  460.         $idea $this->ideaRepository->find($ideaId);
  461.         if (!$idea) {
  462.             $res->validate('noIdea'null'empty'$this->message['noIdea']);
  463.         }
  464.         if (!$res->isValid()) {
  465.             return new JsonResponse($res->result());
  466.         }
  467.         $collection $this->collectionRepository->find($interior->getCollection()->getId());
  468.         $rating $collection->getRating();
  469.         $memcache App::getMemcache();
  470.         $memcache->set('updateCollections'time(), false600);
  471.         $redisCachePool App::getContainer()->get(RedisCachePool::class)->getPool();
  472.         $cacheItem $redisCachePool->getItem('updateCollections');
  473.         $cacheItem->expiresAfter(600);
  474.         $cacheItem->set(time());
  475.         $redisCachePool->save($cacheItem);
  476.         if ($idea->getInteriors()->contains($interior) === false) {
  477.             $active true;
  478.             $idea->getInteriors()->add($interior);
  479.             $interior->getIdeas()->add($idea);
  480.             $collection->setRating($rating 1);
  481.             $this->setIdeaInterior($idea$interiorInteriorHistory::ADD);
  482.             $this->updateFactoryIdeas($collection->getFactory()->getId());
  483.         } elseif ($type != 'add') {
  484.             $active false;
  485.             $idea->getInteriors()->removeElement($interior);
  486.             $interior->getIdeas()->removeElement($idea);
  487.             $collection->setRating(($rating 1) ? $rating $rating);
  488.             $this->setIdeaInterior($idea$interiorInteriorHistory::DEL);
  489.             $this->updateFactoryIdeas($collection->getFactory()->getId(), false);
  490.         } else {
  491.             $active true;
  492.         }
  493.         $this->interiorRepository->save($interiortrue);
  494.         $this->ideaRepository->save($ideatrue);
  495.         $result = [
  496.             'iRating' => (int) $interior->getIdeas()->count(),
  497.             'cRating' => (int) $interior->getCollection()->getRating(),
  498.             'all' => (int) $this->ideaRepository->countByToken($token),
  499.             'active' => $active,
  500.             'projects' => [
  501.                 [
  502.                     'name' => $idea->getName(),
  503.                     'url' => TwigTe::ideaUrl($idea),
  504.                 ],
  505.             ],
  506.         ];
  507.         $res->setResponse('res'$result);
  508.         return new JsonResponse($res->result());
  509.     }
  510.     /**
  511.      * Добавление удаление интерьера из идей
  512.      * @param int $interiorId идентификаторы интерьера
  513.      * @return mixed
  514.      * @throws OptimisticLockException
  515.      * @throws ORMException
  516.      * @throws Exception
  517.      * @internal param int $ideaId идентификатор проекта идеи
  518.      */
  519.     public function changeIdeasInteriorAction(int $interiorId): JsonResponse
  520.     {
  521.         /** @var ResponseApiHelper $response */
  522.         $res = new ResponseApiHelper();
  523.         $token UserHelper::getInstance()->getToken();
  524.         $ideasAction = [];
  525.         if (!empty($_POST['ideas'])) {
  526.             $ideasAction $_POST['ideas'];
  527.         }
  528.         /** @var InteriorRepository $interiorRepo */
  529.         $interiorRepo App::getRepository('WebBundle:Interior');
  530.         /** @var Interior $interiorChange */
  531.         $interiorChange $interiorRepo->getInteriorForIdea($interiorId);
  532.         if (!$interiorChange) {
  533.             $res->validate('noInterior'null'empty'$this->message['noInterior']);
  534.         }
  535.         /** @var Idea $idea */
  536.         $ideas $this->ideaRepository->getIdeas(array_keys($ideasAction), false);
  537.         $rating $interiorChange $interiorChange->getCollection()->getRating() : null;
  538.         if ($res->isValid()) {
  539.             $active false;
  540.             $em App::em();
  541.             $projects = [];
  542.             /** @var Idea $idea */
  543.             foreach ($ideas as $idea) {
  544.                 if (isset($ideasAction[$idea->getId()])) {
  545.                     if ($ideasAction[$idea->getId()] == 1) { // добавление интерьера в проект инеи
  546.                         if (!$idea->getInteriors()->contains($interiorChange)) {
  547.                             $idea->getInteriors()->add($interiorChange);
  548.                             $interiorChange->getIdeas()->add($idea);
  549.                             $this->setIdeaInterior($idea$interiorChange'add');
  550.                             $rating $rating 1;
  551.                         }
  552.                         $active true;
  553.                     } else { // удаление интерьера из проекта идеи
  554.                         if ($idea->getInteriors()->contains($interiorChange)) {
  555.                             $idea->getInteriors()->removeElement($interiorChange);
  556.                             $interiorChange->getIdeas()->removeElement($idea);
  557.                             $this->setIdeaInterior($idea$interiorChange'del');
  558.                             $rating = ($rating 1) ? $rating $rating;
  559.                         }
  560.                     }
  561.                 }
  562.                 $interiorChange->getCollection()->setRating($rating);
  563.                 $this->updateFactoryIdeas($interiorChange->getCollection()->getFactory()->getId(), $active);
  564.                 $em->persist($interiorChange);
  565.                 $em->persist($interiorChange->getCollection());
  566.                 $em->persist($idea);
  567.                 $em->flush();
  568.                 $projects[] = [
  569.                     'name' => $idea->getName(),
  570.                     'url' => TwigTe::ideaUrl($idea)
  571.                 ];
  572.             }
  573.             /** @var IdeaRepository $repoIdea */
  574.             $repoIdea App::getContainer()->get('app.repo.idea');
  575.             $result = [
  576.                 'iRating' => $interiorChange->getIdeas()->count(),
  577.                 'cRating' => $interiorChange->getCollection()->getRating(),
  578.                 'all' => (int)$repoIdea->countByToken($token),
  579.                 'active' => $active,
  580.                 'projects' => $projects
  581.             ];
  582.             $res->setResponse('res'$result);
  583.         }
  584.         return new JsonResponse($res->result());
  585.     }
  586.     /**
  587.      * @param Idea $idea
  588.      * @param Interior $interior
  589.      * @param bool $action
  590.      * @throws Exception
  591.      */
  592.     private function setIdeaInterior(Idea $ideaInterior $interiorbool $action)
  593.     {
  594.         $interiorHistory $this->interiorHistoryRepository->getInteriorHistory($interior->getId(), $idea->getId());
  595.         if (!$interiorHistory) {
  596.             $interiorHistory = new InteriorHistory();
  597.             $interiorHistory->setInterior($interior);
  598.             $interiorHistory->setIdea($idea);
  599.         }
  600.         $interiorHistory->setAction($action);
  601.         $interiorHistory->setDate(new DateTime());
  602.         $this->interiorHistoryRepository->save($interiorHistorytrue);
  603.     }
  604.     /**
  605.      * @param int $ideaId
  606.      * @param int $interiorId
  607.      * @return JsonResponse
  608.      * @throws OptimisticLockException
  609.      * @throws ORMException
  610.      * @throws Exception
  611.      */
  612.     public function delInteriorAction(int $ideaIdint $interiorId): JsonResponse
  613.     {
  614.         $res = new ResponseApiHelper();
  615.         $token UserHelper::getInstance()->getToken();
  616.         /** @var Idea $idea */
  617.         $idea $this->ideaRepository->getIdeaById($ideaId);
  618.         if (!$idea) {
  619.             throw $this->createNotFoundException('Not found idea');
  620.         } elseif ($idea->getToken() != $token) {
  621.             throw $this->createAccessDeniedException();
  622.         }
  623.         /** @var Interior $interiorChange */
  624.         $interiorChange App::getRepository('WebBundle:Interior')->findOneBy(
  625.             ['id' => $interiorId]
  626.         );
  627.         $collection $interiorChange->getCollection();
  628.         $rating $collection->getRating();
  629.         $idea->getInteriors()->removeElement($interiorChange);
  630.         $interiorChange->getIdeas()->removeElement($idea);
  631.         $this->setIdeaInterior($idea$interiorChangeInteriorHistory::DEL);
  632.         $collection->setRating(($rating 1) ? $rating $rating);
  633.         $this->updateFactoryIdeas($interiorChange->getCollection()->getFactory()->getId(), false);
  634.         App::em()->persist($collection);
  635.         App::em()->persist($interiorChange);
  636.         App::em()->persist($idea);
  637.         App::em()->flush();
  638.         /** @var IdeaRepository $repoIdea */
  639.         $repoIdea App::getContainer()->get('app.repo.idea');
  640.         $result = [
  641.             'iRating' => (int)$interiorChange->getIdeas()->count(),
  642.             'cRating' => (int)$interiorChange->getCollection()->getRating(),
  643.             'all' => (int)$repoIdea->countByToken($token),
  644.             'active' => false,
  645.             'projects' => [
  646.                 [
  647.                     'name' => $idea->getName(),
  648.                     'url' => TwigTe::ideaUrl($idea)
  649.                 ]
  650.             ]
  651.         ];
  652.         $res->setResponse('res'$result);
  653.         return new JsonResponse($res->result());
  654.     }
  655.     /**
  656.      * Перемещение интерьера в другой проект
  657.      *
  658.      * @param Request $request
  659.      * @param int $oldIdeaId
  660.      * @param int $interiorId
  661.      * @return JsonResponse
  662.      * @throws ORMException
  663.      * @throws OptimisticLockException
  664.      */
  665.     public function moveInteriorAction(Request $requestint $oldIdeaIdint $interiorId): JsonResponse
  666.     {
  667.         $res = new ResponseApiHelper();
  668.         $this->changeIdeasInteriorAction($interiorId);
  669.         $this->delInteriorAction($oldIdeaId$interiorId);
  670.         $result = [
  671.             'oldIdeaId' => $oldIdeaId,
  672.             'targetIdeaId' => $request->get('ideas'),
  673.             'interiorId' => $interiorId,
  674.         ];
  675.         $res->setResponse('res'$result);
  676.         return new JsonResponse($res->result());
  677.     }
  678.     /**
  679.      * updateFactoryIdeas - Функция по увеличению/уменьшению кол-ва идей для фабрики.
  680.      *
  681.      * @see Collection entity for duplicate #of shared ideas.
  682.      *      sum of all "rating" where (Collection->getFactory = $factoryId)  === Factory->ideas
  683.      *
  684.      * @param int $factoryId - Factory id where increase or decrease interiors stat
  685.      * @param ?bool $isAdded - if True - increase counter, else decrease
  686.      * @return void - Or mb need return boolean :  True - all ok, False - not good
  687.      * @throws ORMException
  688.      * @throws Exception
  689.      */
  690.     private function updateFactoryIdeas(int $factoryId, ?bool $isAdded true)
  691.     {
  692.         $oFactory App::getRepository('WebBundle:Factory')->findOneBy(['id' => $factoryId]);
  693.         if (!$oFactory) {
  694.             return;
  695.         }
  696.         $em App::em();
  697.         $i $oFactory->getTotalIdeas() ?? 0;//get current ideas
  698.         if ($isAdded) {
  699.             //new idea added. +1 to stat in the factory
  700.             $oFactory->setTotalIdeas($i 1);
  701.         } else {
  702.             // idea is deleted. -1 to stat in the factory
  703.             if ($i 0) {
  704.                 $oFactory->setTotalIdeas($i 1);
  705.             }
  706.         }
  707.         if ($i != $oFactory->getTotalIdeas()) {
  708.             //write changes
  709.             $em->persist($oFactory);
  710.             $em->flush();//// ? mb move out from this function for one  persist+flush  functions
  711.         }
  712.     }
  713.     /**
  714.      * @return array
  715.      * @throws Exception
  716.      */
  717.     private function trans(): array
  718.     {
  719.         return [
  720.             'ideaHeaderList' => App::trans('idea_header_list'),
  721.             'ideaUpdateDate' => App::trans('idea_update_date'),
  722.             'ideaAddProject' => App::trans('idea_add_project'),
  723.             'ideaBookEmpty' => App::trans('user.ideabook_empty'),
  724.             'interiorIdeaDelete' => App::trans('interior_idea_dellete'),
  725.             'confirmHeader' => App::trans('buyOrder.confirm.header'),
  726.             'ideaEmpty' => App::trans('idea_empty'),
  727.             'cancel' => App::trans('cancel'),
  728.             'save' => App::trans('save'),
  729.             'yes' => App::trans('yes'),
  730.             'no' => App::trans('no'),
  731.             'rename' => App::trans('rename'),
  732.             'share' => App::trans('share'),
  733.             'delete' => App::trans('idea.button_delete'),
  734.             'delInteriorAllIdeas' => App::trans('idea_del_interior_msg'),
  735.             'copy' => App::trans('copy'),
  736.             'ideaDeleteTitle' => App::trans('idea.del_project'),
  737.             'interiorDeleteTitle' => App::trans('idea_msg_active'),
  738.             'ideaRenameTitle' => App::trans('idea.rename_coll'),
  739.             'ideaShareTitle' => App::trans('idea_share_header'),
  740.             'ideaShareDescr' => App::trans('idea_share_link_can'),
  741.             'shareOnSocial' => App::trans('share_social_network'),
  742.             'ideaNewProject' => App::trans('idea_new_project'),
  743.         ];
  744.     }
  745.     /**
  746.      * @return array
  747.      * @throws Exception
  748.      */
  749.     private function paths(): array
  750.     {
  751.         return [
  752.             'appIdeaDel' => App::generateUrl('app_idea_del', ['id' => 0]),
  753.             'appIdeaEdit' => App::generateUrl('app_idea_edit', ['id' => 0'name' => '-name-']),
  754.             'appIdeaCreate' => App::generateUrl('app_idea_create')
  755.         ];
  756.     }
  757. }