app/Plugin/Schedule/Service/ScheduleService.php line 291

Open in your IDE?
  1. <?php
  2. /**
  3.  * Copyright(c) 2018 SYSTEM_KD
  4.  * Date: 2018/09/30
  5.  */
  6. namespace Plugin\Schedule\Service;
  7. use Doctrine\ORM\EntityManagerInterface;
  8. use Eccube\Entity\Category;
  9. use Eccube\Entity\Page;
  10. use Eccube\Entity\Product;
  11. use Eccube\Entity\ProductCategory;
  12. use Eccube\Repository\CategoryRepository;
  13. use Eccube\Repository\PageRepository;
  14. use Eccube\Repository\ProductRepository;
  15. use Plugin\Schedule\Entity\ScheduleTime;
  16. use Plugin\Schedule\Entity\ScheduleTimeAddTrait;
  17. use Plugin\Schedule\Repository\ScheduleTimeRepository;
  18. use Plugin\Schedule\Utils\ScheduleUtility;
  19. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  20. use Symfony\Component\Translation\TranslatorInterface;
  21. class ScheduleService
  22. {
  23.     /** @var EntityManagerInterface */
  24.     protected $entityManager;
  25.     /** @var ProductRepository */
  26.     protected $productRepository;
  27.     /** @var PageRepository */
  28.     protected $pageRepository;
  29.     /** @var CategoryRepository */
  30.     protected $categoryRepository;
  31.     /** @var TranslatorInterface */
  32.     protected $translator;
  33.     /** @var ScheduleTimeRepository */
  34.     protected $scheduleTimeRepository;
  35.     /** @var ScheduleUtility */
  36.     protected $scheduleUtility;
  37.     /** @var ScheduleHelper */
  38.     protected $scheduleHelper;
  39.     public function __construct(
  40.         EntityManagerInterface $entityManager,
  41.         ProductRepository $productRepository,
  42.         PageRepository $pageRepository,
  43.         CategoryRepository $categoryRepository,
  44.         ScheduleTimeRepository $scheduleTimeRepository,
  45.         TranslatorInterface $translator,
  46.         ScheduleUtility $scheduleUtility,
  47.         ScheduleHelper $scheduleHelper
  48.     )
  49.     {
  50.         $this->entityManager $entityManager;
  51.         $this->productRepository $productRepository;
  52.         $this->pageRepository $pageRepository;
  53.         $this->categoryRepository $categoryRepository;
  54.         $this->translator $translator;
  55.         $this->scheduleTimeRepository $scheduleTimeRepository;
  56.         $this->scheduleUtility $scheduleUtility;
  57.         $this->scheduleHelper $scheduleHelper;
  58.     }
  59.     /**
  60.      * 公開開始・終了日の更新
  61.      *
  62.      * @param $entity
  63.      * @param ScheduleTime $ScheduleTime
  64.      */
  65.     public function updateScheduleTime($entityScheduleTime $ScheduleTime)
  66.     {
  67.         if (!is_null($ScheduleTime)) {
  68.             $time_type $ScheduleTime->getScheduleType();
  69.             if ($ScheduleTime::PRODUCT_TYPE == $time_type) {
  70.                 // 公開日時が未設定の場合は、レコード削除
  71.                 $time_from $ScheduleTime->getTimeFrom();
  72.                 $time_to $ScheduleTime->getTimeTo();
  73.                 // 時間をクリア
  74.                 $ScheduleTime->setTimeOnlyFrom(null);
  75.                 $ScheduleTime->setTimeOnlyTo(null);
  76.             } else {
  77.                 // 公開時間が未設定の場合は、レコード削除
  78.                 $time_from $ScheduleTime->getTimeOnlyFrom();
  79.                 $time_to $ScheduleTime->getTimeOnlyTo();
  80.                 // 期間をクリア
  81.                 $ScheduleTime->setTimeFrom(null);
  82.                 $ScheduleTime->setTimeTo(null);
  83.             }
  84.             // 公開日時or時間が未設定の場合は、レコード削除
  85.             if (is_null($time_from) && is_null($time_to)) {
  86.                 // ScheduleTime削除
  87.                 if (!empty($ScheduleTime->getId())) {
  88.                     $entity->setScheduleTime(null);
  89.                     $this->entityManager->remove($ScheduleTime);
  90.                     $this->entityManager->flush();
  91.                     return;
  92.                 }
  93.             }
  94.             // 更新
  95.             $this->entityManager->persist($ScheduleTime);
  96.             $this->entityManager->flush();
  97.             $entity->setScheduleTime($ScheduleTime);
  98.             $this->entityManager->persist($entity);
  99.             $this->entityManager->flush();
  100.         }
  101.     }
  102.     /**
  103.      * @param Category $entity 紐づく親情報を設定
  104.      * @throws \Doctrine\ORM\ORMException
  105.      * @throws \Doctrine\ORM\OptimisticLockException
  106.      */
  107.     public function updateChainScheduleTime(Category $entity)
  108.     {
  109.         $scheduleTime $entity->getScheduleTime();
  110.         // 紐づく親カテゴリIDを取得
  111.         $chainSchedule $this->getChainSchedule($entity);
  112.         if (is_null($scheduleTime)
  113.             || (is_null($scheduleTime->getTimeFrom()) && is_null($scheduleTime->getTimeTo()))) {
  114.             // ScheduleTime がクリアされた場合
  115.             // 現在自分自身に紐付いている情報を抽出し、親に紐づけ変更
  116.             $this->scheduleTimeRepository->updateChainScheduleTime($entity->getScheduleTime(), $chainSchedule);
  117.             // 公開情報が付与されていないデータを、親に紐づけ
  118.             $this->scheduleTimeRepository->insertChainScheduleTime($entity$chainSchedule);
  119.         } else {
  120.             // ScheduleTimeが設定された場合
  121.             // 自分の子の中で親に紐付いているものを抽出し、自分に紐づけ変更
  122.             $this->scheduleTimeRepository->categoryChildrenUpdate($entity$chainSchedule);
  123.             // 公開情報が付与されていないデータを、自分に紐づけ
  124.             $this->scheduleTimeRepository->insertChainScheduleTime($entity$entity->getScheduleTime());
  125.         }
  126.         $scheduleTime->setChainScheduleTime($chainSchedule);
  127.         $this->entityManager->persist($scheduleTime);
  128.         $this->entityManager->flush();
  129.     }
  130.     /**
  131.      * ScheduleTimeが設定された親情報を返却
  132.      *
  133.      * @param Category $category
  134.      * @return ScheduleTime|null
  135.      */
  136.     private function getChainSchedule(Category $category)
  137.     {
  138.         while (true) {
  139.             $Parent $category->getParent();
  140.             if (is_null($Parent)) break;
  141.             $parentScheduleTime $Parent->getScheduleTime();
  142.             if (!is_null($parentScheduleTime)) {
  143.                 $time_from $parentScheduleTime->getTimeFrom();
  144.                 $time_to $parentScheduleTime->getTimeTo();
  145.                 // 親特定
  146.                 if (!is_null($time_from) || !is_null($time_to)) {
  147.                     return $parentScheduleTime;
  148.                 }
  149.             }
  150.             $category $Parent;
  151.         }
  152.         return null;
  153.     }
  154.     /**
  155.      * EntityとScheduleTimeの紐づけ
  156.      *
  157.      * @param ScheduleTimeAddTrait $entity
  158.      * @param ScheduleTime $scheduleTime
  159.      */
  160.     public function linkScheduleTime($entityScheduleTime $scheduleTime)
  161.     {
  162.         $entity->setScheduleTime($scheduleTime);
  163.         $this->entityManager->persist($entity);
  164.         $this->entityManager->flush();
  165.     }
  166.     /**
  167.      * 非公開時の表示判定
  168.      *
  169.      * @param $product_id
  170.      * @return bool
  171.      */
  172.     public function isViewProduct($product_id)
  173.     {
  174.         $Product $this->getTargetProduct($product_id);
  175.         $ScheduleTime $Product->getScheduleTime();
  176.         if (is_null($ScheduleTime)) {
  177.             // 公開時間指定なし
  178.             return true;
  179.         }
  180.         return ($ScheduleTime->isViewFlg());
  181.     }
  182.     /**
  183.      * 公開状態判定
  184.      *
  185.      * @param ScheduleTime $ScheduleTime
  186.      * @return bool
  187.      * @throws \Exception
  188.      */
  189.     private function isActiveTime(ScheduleTime $ScheduleTime)
  190.     {
  191.         $active true;
  192.         if ($ScheduleTime::PRODUCT_TIME_ONLY_TYPE == $ScheduleTime->getScheduleType()) {
  193.             $nowTime $this->scheduleUtility->getNowTimeOnly();
  194.             // 公開時間判定
  195.             if (!is_null($ScheduleTime->getTimeOnlyFrom())) {
  196.                 if ($ScheduleTime->getTimeOnlyFrom() > $nowTime) {
  197.                     $active false;
  198.                 }
  199.             }
  200.             if (!is_null($ScheduleTime->getTimeOnlyTo())) {
  201.                 if ($ScheduleTime->getTimeOnlyTo() <= $nowTime) {
  202.                     $active false;
  203.                 }
  204.             }
  205.         } else {
  206.             $toDay = new \DateTime();
  207.             // 公開期間判定
  208.             if (!is_null($ScheduleTime->getTimeFrom())) {
  209.                 if ($ScheduleTime->getTimeFrom() > $toDay) {
  210.                     $active false;
  211.                 }
  212.             }
  213.             if (!is_null($ScheduleTime->getTimeTo())) {
  214.                 if ($ScheduleTime->getTimeTo() < $toDay) {
  215.                     $active false;
  216.                 }
  217.             }
  218.         }
  219.         return $active;
  220.     }
  221.     /**
  222.      * 商品公開状態判定
  223.      *
  224.      * @param $product_id
  225.      * @return bool true:公開 false:非公開
  226.      * @throws \Exception
  227.      */
  228.     public function isActiveTimeProduct($product_id)
  229.     {
  230.         $Product $this->getTargetProduct($product_id);
  231.         $ScheduleTime $Product->getScheduleTime();
  232.         if (is_null($ScheduleTime->getId())) {
  233.             // 公開時間指定なし
  234.             // カテゴリ条件チェック
  235.             return $this->isActiveTimeCategories($Product);
  236.         }
  237.         // 公開日時判定
  238.         $active $this->isActiveTime($ScheduleTime);
  239.         return $active;
  240.     }
  241.     /**
  242.      * 所属するカテゴリでの公開状態チェック
  243.      * 非公開ファースト 1つでも非公開のカテゴリがある場合非公開とする
  244.      *
  245.      * @param Product $product
  246.      * @return bool true:公開 false:非公開
  247.      * @throws \Exception
  248.      */
  249.     public function isActiveTimeCategories(Product $product)
  250.     {
  251.         // 所属するカテゴリ取得
  252.         $productCategories $product->getProductCategories();
  253.         $active true;
  254.         /** @var ProductCategory $productCategory */
  255.         foreach ($productCategories as $productCategory) {
  256.             $category $productCategory->getCategory();
  257.             if (!$this->isActiveTimeCategory($category)) {
  258.                 $active false;
  259.                 break;
  260.             }
  261.         }
  262.         return $active;
  263.     }
  264.     /**
  265.      * カテゴリの公開状態判定
  266.      *
  267.      * @param Category $category
  268.      * @return bool true:公開 false:非公開
  269.      * @throws \Exception
  270.      */
  271.     private function isActiveTimeCategory(Category $category)
  272.     {
  273.         $ScheduleTime $category->getScheduleTime();
  274.         if (is_null($ScheduleTime)) {
  275.             // 公開時間指定なし
  276.             return true;
  277.         }
  278.         $active $this->isActiveTime($ScheduleTime);
  279.         return $active;
  280.     }
  281.     /**
  282.      * 販売終了判定
  283.      *
  284.      * @param $product_id
  285.      * @return bool
  286.      * @throws \Exception
  287.      */
  288.     public function isActiveTimeProductEnd($product_id)
  289.     {
  290.         $Product $this->getTargetProduct($product_id);
  291.         $ScheduleTime $Product->getScheduleTime();
  292.         if (is_null($ScheduleTime)) {
  293.             // 公開時間指定なし
  294.             return true;
  295.         }
  296.         $toDay = new \DateTime();
  297.         $isActiveEnd false;
  298.         if($ScheduleTime::PRODUCT_TIME_ONLY_TYPE == $ScheduleTime->getScheduleType()) {
  299.             if(!is_null($ScheduleTime->getTimeOnlyTo())) {
  300.                 if ($ScheduleTime->getTimeOnlyTo() <= $toDay->format('Hi')) {
  301.                     $isActiveEnd true;
  302.                 }
  303.             }
  304.         } else {
  305.             if (!is_null($ScheduleTime->getTimeTo())) {
  306.                 if ($ScheduleTime->getTimeTo() <= $toDay) {
  307.                     $isActiveEnd true;
  308.                 }
  309.             }
  310.         }
  311.         return $isActiveEnd;
  312.     }
  313.     /**
  314.      * @param $product_id
  315.      * @return Product
  316.      */
  317.     private function getTargetProduct($product_id)
  318.     {
  319.         if ($product_id instanceof Product) {
  320.             $Product $product_id;
  321.         } else {
  322.             $Product $this->productRepository->find($product_id);
  323.         }
  324.         if (is_null($Product)) {
  325.             throw new NotFoundHttpException();
  326.         }
  327.         return $Product;
  328.     }
  329.     /**
  330.      * 公開日時判定ページ用
  331.      *
  332.      * @param Page $page
  333.      * @return bool
  334.      * @throws \Exception
  335.      */
  336.     public function isActiveTimePage(Page $page)
  337.     {
  338.         $ScheduleTime $page->getScheduleTime();
  339.         return $this->isActiveTime($ScheduleTime);
  340.     }
  341.     /**
  342.      * カテゴリの公開日時情報を返却
  343.      *
  344.      * @return array
  345.      */
  346.     public function getCategoryScheduleList()
  347.     {
  348.         $Categories $this->categoryRepository->findAll();
  349.         $timeList = [];
  350.         /** @var Category $category */
  351.         foreach ($Categories as $category) {
  352.             $scheduleTime $category->getScheduleTime();
  353.             if (is_null($scheduleTime)) {
  354.                 $timeList[$category->getId()] = "";
  355.             } else {
  356.                 if (!is_null($scheduleTime->getTimeFrom()) || !is_null($scheduleTime->getTimeTo())) {
  357.                     $msg "公開日時:";
  358.                     if (!is_null($scheduleTime->getTimeFrom())) {
  359.                         $msg .= $scheduleTime->getTimeFromString();
  360.                     }
  361.                     $msg .= ' ~ ';
  362.                     if (!is_null($scheduleTime->getTimeTo())) {
  363.                         $msg .= $scheduleTime->getTimeToString();
  364.                     }
  365.                 } else {
  366.                     $msg '';
  367.                 }
  368.                 $timeList[$category->getId()] = $msg;
  369.             }
  370.         }
  371.         return $timeList;
  372.     }
  373.     /**
  374.      * 商品が公開される公開日時を返却
  375.      *
  376.      * @param Product $product
  377.      * @return ScheduleTime|null
  378.      */
  379.     public function getActiveScheduleTime(Product $product)
  380.     {
  381.         // 商品に公開日時が設定されている場合 最優先
  382.         $scheduleTime $product->getScheduleTime();
  383.         if (!is_null($scheduleTime) && !empty($scheduleTime->getId())) {
  384.             return $scheduleTime;
  385.         }
  386.         // 設定されているカテゴリからアクティブな時間を取得
  387.         $productCategories $product->getProductCategories();
  388.         $scheduleTimeTemp = new ScheduleTime();
  389.         /** @var ProductCategory $productCategory */
  390.         foreach ($productCategories as $productCategory) {
  391.             // 最大のFrom と 最小のToを取得
  392.             $category $productCategory->getCategory();
  393.             $scheduleTime $category->getScheduleTime();
  394.             if (is_null($scheduleTime)) {
  395.                 // 公開時間指定なし
  396.                 continue;
  397.             }
  398.             // 最大のFrom 設定
  399.             if (is_null($scheduleTimeTemp->getTimeFrom())) {
  400.                 $scheduleTimeTemp->setTimeFrom($scheduleTime->getTimeFrom());
  401.             } else if (!is_null($scheduleTime->getTimeFrom())) {
  402.                 if ($scheduleTimeTemp->getTimeFrom() < $scheduleTime->getTimeFrom()) {
  403.                     $scheduleTimeTemp->setTimeFrom($scheduleTime->getTimeFrom());
  404.                 }
  405.             }
  406.             // 最小のTo 設定
  407.             if (is_null($scheduleTimeTemp->getTimeTo())) {
  408.                 $scheduleTimeTemp->setTimeTo($scheduleTime->getTimeTo());
  409.             } else if (!is_null($scheduleTime->getTimeTo())) {
  410.                 if ($scheduleTimeTemp->getTimeTo() > $scheduleTime->getTimeTo()) {
  411.                     $scheduleTimeTemp->setTimeTo($scheduleTime->getTimeTo());
  412.                 }
  413.             }
  414.             // view
  415.             // いずれか1つでも表示がある場合は表示優先
  416.             if (!$scheduleTimeTemp->isTimeViewFlg()) {
  417.                 $scheduleTimeTemp->setTimeViewFlg($scheduleTime->isTimeViewFlg());
  418.             }
  419.         }
  420.         return $scheduleTimeTemp;
  421.     }
  422.     /**
  423.      * 商品が公開される公開日時を文字列で返却
  424.      *
  425.      * @param Product $product
  426.      * @return array
  427.      */
  428.     public function getActiveScheduleTimeToString(Product $product)
  429.     {
  430.         $scheduleTimeTmp $this->getActiveScheduleTime($product);
  431.         $scheduleFromMsg $this->translator->trans('schedule.time_empty');
  432.         $scheduleToMsg $this->translator->trans('schedule.time_empty');
  433.         if (ScheduleTime::PRODUCT_TIME_ONLY_TYPE == $scheduleTimeTmp->getScheduleType()) {
  434.             // 公開時間
  435.             if (!is_null($scheduleTimeTmp->getTimeOnlyFrom())) {
  436.                 $scheduleFromMsg $this->scheduleHelper->getTimeFormat($scheduleTimeTmp->getTimeOnlyFrom());
  437.             }
  438.             if (!is_null($scheduleTimeTmp->getTimeOnlyTo())) {
  439.                 $scheduleToMsg $this->scheduleHelper->getTimeFormat($scheduleTimeTmp->getTimeOnlyTo());
  440.             }
  441.         } else {
  442.             // 公開期間
  443.             if (!is_null($scheduleTimeTmp->getTimeFrom()) && !is_null($scheduleTimeTmp->getTimeTo())) {
  444.                 if ($scheduleTimeTmp->getTimeFrom() > $scheduleTimeTmp->getTimeTo()) {
  445.                     // 公開不可の設定状態
  446.                     $scheduleFromMsg $this->translator->trans('schedule.time_ng');
  447.                     $scheduleToMsg $this->translator->trans('schedule.time_ng');
  448.                 } else {
  449.                     $scheduleFromMsg $scheduleTimeTmp->getTimeFromString();
  450.                     $scheduleToMsg $scheduleTimeTmp->getTimeToString();
  451.                 }
  452.             } else {
  453.                 if (!is_null($scheduleTimeTmp->getTimeFrom())) {
  454.                     $scheduleFromMsg $scheduleTimeTmp->getTimeFromString();
  455.                 }
  456.                 if (!is_null($scheduleTimeTmp->getTimeTo())) {
  457.                     $scheduleToMsg $scheduleTimeTmp->getTimeToString();
  458.                 }
  459.             }
  460.         }
  461.         return [
  462.             'scheduleFromMsg' => $scheduleFromMsg,
  463.             'scheduleToMsg' => $scheduleToMsg
  464.         ];
  465.     }
  466.     /**
  467.      * 公開設定が時間か判定
  468.      *
  469.      * @param $Product Product
  470.      * @return bool true:時間 false:期間
  471.      */
  472.     public function isScheduleTypeTimeOnly(Product $Product)
  473.     {
  474.         $ScheduleTime $Product->getScheduleTime();
  475.         if (!is_null($ScheduleTime)) {
  476.             if ($ScheduleTime::PRODUCT_TIME_ONLY_TYPE == $ScheduleTime->getScheduleType()) {
  477.                 return true;
  478.             }
  479.         }
  480.         return false;
  481.     }
  482. }