app/Plugin/ScheduleDx/Service/ScheduleService.php line 396

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