app/Customize/Controller/Mypage/MypageController.php line 1064

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.ec-cube.co.jp/
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Customize\Controller\Mypage;
  13. use Carbon\Carbon;
  14. use Customize\Controller\LM\LmAbstractController;
  15. use Customize\Event\LmEvents;
  16. use Customize\Service\CommonService;
  17. use Customize\Service\FavoriteService;
  18. use Customize\Service\ImageService;
  19. use Customize\Service\LmHelper;
  20. use Customize\Service\MobileDetector as LmMobileDetector;
  21. use Eccube\Entity\Customer;
  22. use Customize\Entity\CustomerFavoriteProductTrait;
  23. use Eccube\Entity\CustomerFavoriteProduct;
  24. use Eccube\Entity\Product;
  25. use Eccube\Event\EccubeEvents;
  26. use Eccube\Event\EventArgs;
  27. use Customize\Repository\CustomerFavoriteProductRepository;
  28. use Eccube\Form\Type\Front\CustomerLoginType;
  29. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  30. use Symfony\Component\HttpFoundation\Request;
  31. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  32. use Symfony\Component\Routing\Annotation\Route;
  33. use Customize\Service\CustomerService;
  34. use Customize\Service\OrderService;
  35. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  36. use Customize\Controller\ApiController;
  37. use Knp\Component\Pager\PaginatorInterface;
  38. use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
  39. use Lm\Service\Store\FileStoreService;
  40. use Symfony\Component\HttpFoundation\StreamedResponse;
  41. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  42. use Lm\Engine\Zaiko\Entity\SkuExtended;
  43. use Lm\Entity\GoodsColor;
  44. use Lm\Entity\GoodsPrice;
  45. use Lm\Service\Coupon\Coupon;
  46. class MypageController extends LmAbstractController
  47. {
  48.     protected $CommonService;
  49.     protected $CustomerService;
  50.     protected $OrderService;
  51.     /**
  52.      * @var CustomerFavoriteProductRepository
  53.      */
  54.     protected $customerFavoriteProductRepository;
  55.     protected $CFIMG_URL "https://img0.land-mark.biz/ut_img";
  56.     /**
  57.      * @var LmMobileDetector
  58.      */
  59.     private $mobileDetector;
  60.     /**
  61.      * @var FavoriteService
  62.      */
  63.     private $favoriteService;
  64.     public function __construct(
  65.         CustomerFavoriteProductRepository $customerFavoriteProductRepository,
  66.         CommonService   $commonService,
  67.         LmHelper        $lmHelper,
  68.         CustomerService $CustomerService,
  69.         OrderService    $OrderService,
  70.         LmMobileDetector       $mobileDetector,
  71.         FavoriteService $favoriteService
  72.     )
  73.     {
  74.         //
  75.         parent::__construct($commonService$lmHelper);
  76.         $this->customerFavoriteProductRepository $customerFavoriteProductRepository;
  77.         $this->CommonService $commonService;
  78.         $this->CustomerService $CustomerService;
  79.         $this->OrderService $OrderService;
  80.         $this->mPayment $lmHelper->getPaymentTypeList();
  81.         $this->DOW $lmHelper->getDayOfWeek();
  82.         $this->mobileDetector $mobileDetector;
  83.         $this->favoriteService $favoriteService;
  84.     }
  85.     /**
  86.      * マイページ
  87.      *
  88.      * @Route("/mypage/", name="mypage", methods={"GET"})
  89.      * @Template("Mypage/index.twig")
  90.      */
  91.     public function index(Request $request)
  92.     {
  93.         $Customer $this->getUser();
  94.         if(!$Customer) {
  95.             return $this->redirectToRoute('mypage_login');
  96.         }
  97.         $lmCustomerId $Customer->getLmCustomerId();
  98.         #LMカスタマーを取得
  99.         $lmCustomer $this->CustomerService->GetLandMarkCustomerId($lmCustomerId);
  100.         $mailDisp 0;
  101.         if (strlen($lmCustomer['customer_mail']) > 25 and isset($lmCustomer["customer_mail"]) and $lmCustomer["customer_mail"] != "" and preg_match("/@/"$lmCustomer["customer_mail"])) {
  102.             $mailDisp 1;
  103.         }
  104.         $data $this->OrderService->getDispCount ($lmCustomerId);
  105.         // Coupon logic using vendor/lm/engine-coupon functions
  106.         $coupons = [];
  107.         $customerBangou $lmCustomer['customer_bangou'] ?? null;
  108.         $customerId $lmCustomer['customer_id'] ?? null;
  109.         
  110.         if ($customerBangou) {
  111.             // Initialize coupon engine (no PDO needed - uses SqlService internally)
  112.             $couponEngine = new Coupon();
  113.             // Get all available coupons for the customer
  114.             $availableCoupons $couponEngine->getAvailableCouponList($customerBangou$customerId, new \DateTime());
  115.             // Process each coupon according to requirements
  116.             foreach ($availableCoupons as $campaign) {
  117.                 $couponData = [
  118.                     'id' => $campaign->getCouponCampaignId(),
  119.                     'title' => $campaign->getCouponCampaignTitle() ?: 'クーポン',
  120.                     'coupon_campaign_display_name' => $campaign->getCouponCampaignDisplayName() ?: 'クーポン',
  121.                     'description' => $campaign->getCouponCampaignComment() ?: '',
  122.                     'code' => $campaign->getCouponCampaignCode() ?: '',
  123.                     'target' => $campaign->getCouponCampaignTarget(),
  124.                     'discount_amount' => $campaign->getCouponCampaignDiscount(),
  125.                     'price' => $campaign->getCouponCampaignPrice(),
  126.                     'expires_at' => $campaign->getCouponCampaignEndDate(),
  127.                     'start_date' => $campaign->getCouponCampaignStartDate(),
  128.                     'type' => $this->getCouponType($campaign->getCouponCampaignTarget(), $lmCustomer),
  129.                     'status' => $this->getCouponStatus($campaign->getCouponCampaignEndDate())
  130.                 ];
  131.                 
  132.                 $coupons[] = $couponData;
  133.             }
  134.             
  135.             // Sort by expiration date (ascending - closest to expiration first) - Requirement 0
  136.             usort($coupons, function($a$b) {
  137.                 $dateA = new \DateTime($a['expires_at']);
  138.                 $dateB = new \DateTime($b['expires_at']);
  139.                 return $dateA <=> $dateB;
  140.             });
  141.             // Filter coupons based on user's order status
  142.             $hasOrders false;
  143.             if ($History $this->OrderService->getHistory($lmCustomerId)) {
  144.                 $hasOrders count($History) > 0;
  145.             }
  146.             $coupons array_values(array_filter($coupons, function ($c) use ($hasOrders$lmCustomer) {
  147.                 if (isset($c['type']) && $c['type'] === 'newsletter' && $lmCustomer['customer_melmaga'] == 1) {
  148.                     return true;
  149.                 }
  150.             
  151.                 if (isset($c['type']) && $c['type'] === 'first_purchase' && !$hasOrders) {
  152.                     return true;
  153.                 }
  154.                 if (isset($c['type']) && $c['type'] === 'customer_feedback_without_photo') {
  155.                     return true;
  156.                 }
  157.                 if (isset($c['type']) && $c['type'] === 'customer_feedback_with_photo') {
  158.                     return true;
  159.                 }
  160.                 if (isset($c['type']) && $c['type'] === 'for_all_customer') {
  161.                     return true;
  162.                 }
  163.                 if (isset($c['type']) && $c['type'] === 'spot_mail') {
  164.                     return true;
  165.                 }
  166.             
  167.                 return false;
  168.             }));
  169.         }
  170.         $main_h1 null;
  171.         $category_h1 null;
  172.         $h1_comment null;
  173.         $common_header_contents_all '';
  174.         $common_header_contents null;
  175.         $recentviews = [];
  176.         $custom_menu null;
  177.         $custom_frequently_searched_word null;
  178.         // ビュー(テンプレート)へデータを渡す
  179.         return [
  180.             'lmCustomer' => $lmCustomer,
  181.             'CFIMG_URL' => $this->CFIMG_URL,
  182.             'data' => $data,
  183.             'main_h1' => $main_h1,
  184.             'mailDisp' => $mailDisp,
  185.             'category_h1' => $category_h1,
  186.             'h1_comment' => $h1_comment,
  187.             'common_header_contents_all' => $common_header_contents_all,
  188.             'common_header_contents' => $common_header_contents,
  189.             'recentviews' => $recentviews,
  190.             'custom_menu' => $custom_menu,
  191.             'custom_frequently_searched_word' => $custom_frequently_searched_word,
  192.             'BreadCrumbs' => [],
  193.             'coupons' => $coupons,
  194.         ];
  195.     }
  196.     /**
  197.      * お気に入り商品を表示する.
  198.      *
  199.      * @Route("/mypage/favorite/", name="mypage_favorite", methods={"GET"})
  200.      * @Template("Mypage/favorite.twig")
  201.      */
  202.     public function favorite(Request $requestPaginatorInterface $paginator)
  203.     {
  204.         $sort $request->get('s'1);
  205.         $itemStart $request->get('no'0);
  206.         $pageLimit 10;
  207.         $Customer $this->getUser();
  208.         if(!$Customer) {
  209.             throw new AccessDeniedHttpException("Err1 このページは表示できません。");
  210.         }
  211.         $lmCustomerId $Customer->getLmCustomerId();
  212.         #LMカスタマーを取得
  213.         $lmCustomer $this->CustomerService->GetLandMarkCustomerId($lmCustomerId);
  214.         $mailDisp 0;
  215.         if (strlen($lmCustomer['customer_mail']) > 25 and isset($lmCustomer["customer_mail"]) and $lmCustomer["customer_mail"] != "" and preg_match("/@/"$lmCustomer["customer_mail"])) {
  216.             $mailDisp 1;
  217.         }
  218.         $main_h1 null;
  219.         $category_h1 null;
  220.         $h1_comment null;
  221.         $common_header_contents_all '';
  222.         $common_header_contents null;
  223.         $recentviews = [];
  224.         $custom_menu null;
  225.         $custom_frequently_searched_word null;
  226.         $data=[];
  227.         $BreadCrumbs = [
  228.             => $this->__getBreadCrumbs_MyPageTop(),
  229.         ];
  230.         $data $this->favoriteService->getFavoriteList ($sort$lmCustomerId$itemStart$pageLimit);
  231.         $totalItem $this->favoriteService->getTotalFavorites ($lmCustomerId);
  232.         return [
  233.             'lmCustomer' => $lmCustomer,
  234.             'CFIMG_URL' => $this->CFIMG_URL,
  235.             'sort' => $sort,
  236.             'mailDisp' => $mailDisp,
  237.             'data' => $data,
  238.             'main_h1' => $main_h1,
  239.             'category_h1' => $category_h1,
  240.             'h1_comment' => $h1_comment,
  241.             'common_header_contents_all' => $common_header_contents_all,
  242.             'common_header_contents' => $common_header_contents,
  243.             'recentviews' => $recentviews,
  244.             'custom_menu' => $custom_menu,
  245.             'custom_frequently_searched_word' => $custom_frequently_searched_word,
  246.             'BreadCrumbs' => $BreadCrumbs,
  247.             'totalItem' => $totalItem,
  248.             'itemStart' => $itemStart 1,
  249.             'itemEnd' => ($itemStart $pageLimit) > $totalItem $totalItem $itemStart $pageLimit,
  250.             'currentPage' => (int)$itemStart/10 1,
  251.             'totalPage' => ceil($totalItem/10),
  252.         ];
  253.     }
  254.     /**
  255.      * @Route("/mypage/add_favorite/{goods_id}/", name="mypage_add_favorite", methods={"GET"})
  256.      * @Template("Mypage/favorite.twig")
  257.      */
  258.     public function addFavorite(Request $request)
  259.     {
  260.         $customer $this->getUser();
  261.         if (!$customer) {
  262.             return $this->redirect($this->generateUrl('mypage_login'));
  263.         }
  264.         $goodsId $request->get('goods_id');
  265.         $goods $this->favoriteService->getGoodsById($goodsId);
  266.         if (empty($goods)) {
  267.             $this->favoriteService->setFavoriteFlashMessage("商品が見つかりません。もう一度はじめからやり直してください。");
  268.         } else {
  269.             $isFavoriteGoods $this->favoriteService->isFavoriteGoods($goodsId$customer->getLmCustomerId());
  270.             if ($isFavoriteGoods) {
  271.                 $this->favoriteService->setFavoriteFlashMessage("既にお気に入りリストに登録されています。");
  272.             } else {
  273.                 $this->favoriteService->addFavorite([
  274.                     'mylist_customer' => $customer->getLmCustomerId(),
  275.                     'mylist_goods' => $goodsId,
  276.                     'mylist_comment' => null,
  277.                     'mylist_rank' => null,
  278.                     'mylist_date' => Carbon::now(),
  279.                 ]);
  280.                 $this->favoriteService->setFavoriteFlashGoods($goods);
  281.                 //
  282.                 $event = new EventArgs([
  283.                     'goods_id' => $goodsId,
  284.                 ], $request);
  285.                 $this->eventDispatcher->dispatch($eventLmEvents::FRONT_PRODUCT_FAVORITE_ADD_COMPLETE);
  286.             }
  287.         }
  288.         return $this->redirect($this->generateUrl('mypage_favorite'));
  289.     }
  290.     /**
  291.      * お気に入り商品を削除する.
  292.      *
  293.      * @Route("/mypage/favorite/{id}/comment/", name="mypage_favorite_comment", methods={"POST"}, requirements={"id" = "\\d+"})
  294.      * @Template("Mypage/favorite_print.twig")
  295.      */
  296.     public function comment(Request $request$id)
  297.     {
  298.         if (!$request->isXmlHttpRequest()) {
  299.             throw new BadRequestHttpException();
  300.         }
  301.         $this->isTokenValid();
  302.         $Customer $this->getUser();
  303.         $lmCustomerId $Customer->getLmCustomerId();
  304.         log_info('お気に入りコメント開始', [$lmCustomerId$id]);
  305.         if ($id) {
  306.             $result $this->favoriteService->addComment($id$request->get('comment'), $request->get('rank'));
  307.             if ($result) {
  308.                 return $this->json(['success' => true]);
  309.             }
  310.         }
  311.         return $this->json(['success' => false]);
  312.     }
  313.     /**
  314.      * お気に入り商品を削除する.
  315.      *
  316.      * @Route("/mypage/favorite/print/", name="mypage_favorite_print", methods={"GET"})
  317.      * @Template("Mypage/favorite_print.twig")
  318.      */
  319.     public function favorite_print(Request $request)
  320.     {
  321.         $sort $request->get('s'1);
  322.         $Customer $this->getUser();
  323.         if(!$Customer) {
  324.             throw new AccessDeniedHttpException("Err1 このページは表示できません。");
  325.         }
  326.         $lmCustomerId $Customer->getLmCustomerId();
  327.         #LMカスタマーを取得
  328.         $lmCustomer $this->CustomerService->GetLandMarkCustomerId($lmCustomerId);
  329.         $FavoriteProducts $this->favoriteService->getFavoriteList ($sort$lmCustomerId00);
  330.         $BreadCrumbs = [
  331.             => $this->__getBreadCrumbs_MyPageTop(),
  332.         ];
  333.         return [
  334.             'lmCustomer' => $lmCustomer,
  335.             'CFIMG_URL' => $this->CFIMG_URL,
  336.             'FavoriteProducts' => $FavoriteProducts,
  337.             'BreadCrumbs' => $BreadCrumbs,
  338.         ];
  339.     }
  340.     /**
  341.      * お気に入り商品を削除する.
  342.      *
  343.      * @Route("/mypage/favorite/{id}/delete", name="mypage_favorite_delete", methods={"DELETE"}, requirements={"id" = "\d+"})
  344.      * @param Request $request
  345.      * @param $id
  346.      * @return \Symfony\Component\HttpFoundation\RedirectResponse
  347.      */
  348.     public function delete(Request $request$id)
  349.     {
  350.         $this->isTokenValid();
  351.         $Customer $this->getUser();
  352.         log_info('お気に入り商品削除開始', [$Customer->getLmCustomerId(), $id]);
  353.         $this->favoriteService->deleteFavorite ($id);
  354.         //
  355.         $event = new EventArgs([
  356.             'goods_id' => $id,
  357.         ], $request);
  358.         $this->eventDispatcher->dispatch($eventLmEvents::FRONT_PRODUCT_FAVORITE_DELETE_COMPLETE);
  359.         log_info('お気に入り商品削除完了', [$Customer->getLmCustomerId(), $id]);
  360.         return $this->redirect($this->generateUrl('mypage_favorite'));
  361.     }
  362.     /**
  363.      * マイページ / 購入履歴・再注文(名入れ無し)
  364.      *
  365.      * @Route("/mypage/history/", name="mypage/history", methods={"GET"})
  366.      * @Template("Mypage/history.twig")
  367.      */
  368.     public function history(Request $request)
  369.     {
  370.         $mSiteType $this->lmHelper->getSiteTypeList();
  371.         /**
  372.          * @var Customer $Customer
  373.          */
  374.         $Customer $this->getUser();
  375.         $lmCustomerId $Customer->getLmCustomerId();
  376.         #LMカスタマーを取得
  377.         $lmCustomer $this->CustomerService->GetLandMarkCustomerId($lmCustomerId);
  378.         // 会員のメール表示切替用
  379.         $mailDisp 0;
  380.         if (strlen($lmCustomer['customer_mail']) > 25 and isset($lmCustomer["customer_mail"]) and $lmCustomer["customer_mail"] != "" and preg_match("/@/"$lmCustomer["customer_mail"])) {
  381.             $mailDisp 1;
  382.         }
  383.         // メモ欄: LM成り代わりログイン時のみ表示 sessionについて確認必要
  384.         $memoDisp 0;
  385.         if (isset($_SESSION["landmark_fax_login"]) and $_SESSION["landmark_fax_login"] != "") {
  386.             $memoDisp 1;
  387.         }
  388.         // 購入履歴一覧の取得
  389.         $orderList=[];
  390.         $goodsList=[];
  391.         if( $History $this->OrderService->getHistory($lmCustomerId) ){
  392.             $no count($History);
  393.             foreach($History as $v){
  394.                 $shipping_infos = [];
  395.                 
  396.                 if ($v['has_sendsheet'] == 1) {
  397.                     $shipping_infos $this->OrderService->getShippingInfo($v['oh_id']);
  398.                 }
  399.                 
  400.                 // Get campaign discount items from OrderItems
  401.                 $campaignDiscounts $this->OrderService->getCampaignDiscountItems($v['oh_id']);
  402.                 $orderList[] = [
  403.                     'no'=> $no,
  404.                     'order'=>$v['oh_shubetsu'].'-'.$v['oh_id'],
  405.                     'date'=>$v['oh_date'],
  406.                     'payment'=>$this->mPayment[$v['oh_payment']],
  407.                     'new_kakunin_id'=>$v['new_kakunin_id'],
  408.                     'oh_id'=>$v['oh_id'],
  409.                     'oh_torikeshi'=>$v['oh_torikeshi'],
  410.                     'koguchi'=>$v['koguchi'],
  411.                     'oh_coupon_discount'=>$v['oh_coupon_discount'],
  412.                     'oh_discount'=>$v['oh_discount'],
  413.                     'oh_campaign_discount'=>$v['oh_campaign_discount'],
  414.                     'oh_campaign_description'=>$v['oh_campaign_description'],
  415.                     'campaign_discounts'=>$campaignDiscounts,
  416.                     'oh_sendcharge'=>$v['oh_sendcharge'],
  417.                     'oh_sendcharge_service'=>$v['oh_sendcharge_service'],
  418.                     'oh_daibiki'=>$v['oh_daibiki'],
  419.                     'oh_daibiki_service'=>$v['oh_daibiki_service'],
  420.                     'oh_atobarai'=>$v['oh_atobarai'],
  421.                     'oh_atobarai_service'=>$v['oh_atobarai_service'],
  422.                     'oh_sumary'=>$v['oh_sumary'],
  423.                     'oh_zeus_linkpoint_flg'=>$v['oh_zeus_linkpoint_flg'],
  424.                     'has_sendsheet'=>$v['has_sendsheet'],
  425.                     'spr_pdate'=>$v['spr_pdate'],
  426.                     'shipping_infos'=> $shipping_infos,
  427.                 ];
  428.                 $goodsList[$no] = $this->OrderService->getHistoryGoods($v['oh_id']);
  429.                 $no $no-1;
  430.             }
  431.         }
  432.         $orderCnt count($History);
  433.         $page $request->query->get('page'1);     // ?pageの指定がない場合は1ページ目とする
  434.         $itemsPerPage=10;
  435.         $max_paging_links 10;
  436.         if ($this->mobileDetector->isMobile()) {
  437.             $max_paging_links 4;
  438.         }
  439.         $pager LmHelper::paging($page$orderList$itemsPerPage$max_paging_links);
  440.         $page_offset $pager['page_offset'];
  441.         $orderList array_slice($orderList$page_offset$itemsPerPage);
  442.         $pager['anKaishi'] = $pager['total_count']-$page_offset;
  443.         $anOwari $pager['anKaishi'] - $itemsPerPage +1;
  444.         if ($anOwari 1) {
  445.             $anOwari 1;
  446.         }
  447.         $pager['anOwari'] = $anOwari;
  448.         $main_h1 null;
  449.         $category_h1 null;
  450.         $h1_comment null;
  451.         $common_header_contents_all '';
  452.         $common_header_contents null;
  453.         $recentviews = [];
  454.         $custom_menu null;
  455.         $custom_frequently_searched_word null;
  456.         $data=[];
  457.         $review = [];
  458.         $BreadCrumbs = [
  459.             => $this->__getBreadCrumbs_MyPageTop(),
  460.         ];
  461.         $countAllOrder = [];
  462.         if ($this->mobileDetector->isMobile()) {
  463.             $countAllOrder $this->OrderService->getDispCount($lmCustomerId);
  464.         }
  465.         if(count($goodsList) > 0){
  466.             $this->checkOutOfStock($goodsList);
  467.         }
  468.         // ビュー(テンプレート)へデータを渡す
  469.         return [
  470.             'lmCustomerId' => $lmCustomerId,
  471.             'lmCustomer' => $lmCustomer,
  472.             'orderCnt' => $orderCnt,
  473.             'orderList' => $orderList,
  474.             'goodsList' => $goodsList,
  475.             'mPayment' => $this->mPayment,   // TODO: Don't do that.
  476.             'mSiteType' => $mSiteType// TODO: Don't do that.
  477.             'mailDisp' => $mailDisp,
  478.             'memoDisp' => $memoDisp,
  479.             'pager' => $pager,
  480.             'data' => $data,
  481.             'main_h1' => $main_h1,
  482.             'category_h1' => $category_h1,
  483.             'h1_comment' => $h1_comment,
  484.             'common_header_contents_all' => $common_header_contents_all,
  485.             'common_header_contents' => $common_header_contents,
  486.             'recentviews' => $recentviews,
  487.             'custom_menu' => $custom_menu,
  488.             'custom_frequently_searched_word' => $custom_frequently_searched_word,
  489.             'review' => $review,
  490.             'BreadCrumbs' => $BreadCrumbs,
  491.             'countAllOrder' => $countAllOrder
  492.         ];
  493.     }
  494.     private function checkOutOfStock(&$goodsList$isHistory true){
  495.         foreach($goodsList as &$goods){
  496.             foreach($goods as &$item){
  497.                 foreach($item as &$child){
  498.                     if(!$isHistory){
  499.                         $child = &$child['goods'];
  500.                     }
  501.                     foreach($child as &$childItem){
  502.                         $sku SkuExtended::getInstance(nullnull$childItem['gcl_id'], $childItem['gp_id']);
  503.                         if ($sku->isNoDisplay() || $sku->getGclDisplayStatus() === GoodsColor::DISPLAY_STATUS_UNAVAILABLE || $sku->getGpDisplay() === GoodsPrice::DISPLAY_HIDDEN) {
  504.                             $childItem['is_out_of_stock'] = true;
  505.                         }else{
  506.                             $childItem['is_out_of_stock'] = false;
  507.                         }
  508.                     }
  509.                 }
  510.             }
  511.         }
  512.     }
  513.     /**
  514.      * マイページ / 購入履歴・再注文(名入れ有り)
  515.      *
  516.      * @param Request $request
  517.      * @param ImageService $imageService
  518.      * @Route("/mypage/mhistory/", name="mypage/mhistory", methods={"GET"})
  519.      * @Template("Mypage/mhistory.twig")
  520.      * @return array
  521.      */
  522.     public function mhistory(Request $requestImageService $imageService)
  523.     {
  524.         $Customer $this->getUser();
  525.         $lmCustomerId $Customer->getLmCustomerId();
  526.         #LMカスタマーを取得
  527.         $lmCustomer $this->CustomerService->GetLandMarkCustomerId($lmCustomerId);
  528.         // 会員のメール表示切替用
  529.         $mailDisp 0;
  530.         if (strlen($lmCustomer['customer_mail']) > 25 and isset($lmCustomer["customer_mail"]) and $lmCustomer["customer_mail"] != "" and preg_match("/@/"$lmCustomer["customer_mail"])) {
  531.             $mailDisp 1;
  532.         }
  533.         // メモ欄: LM成り代わりログイン時のみ表示 sessionについて確認必要
  534.         $memoDisp 0;
  535.         if (isset($_SESSION["landmark_fax_login"]) and $_SESSION["landmark_fax_login"] != "") {
  536.             $memoDisp 1;
  537.         }
  538.         // 購入履歴一覧の取得
  539.         $orderList=[];
  540.         $goodsList=[];
  541.         if( $History $this->OrderService->getMhistory($lmCustomerId) ){
  542.             $no count($History);
  543.             foreach($History as $v){
  544.                 $img="/kanri_img/images/new_kakunin_img/" $v['oh_id'] . ".jpg";
  545.                 // $sslimageType = "kakunin";
  546.                 // $file_headers = @get_headers($img);
  547.                 // if($file_headers[0] != 'HTTP/1.1 403 Forbidden' or strpos( $file_headers[0],"OK" )){
  548.                 //     list($width, $height) = @getimagesize($img);
  549.                 // }
  550.                 // if (empty($width)) {
  551.                 //     $img="/kanri_img/images/kakunin_img/" . $v['oh_id'] . ".jpg";
  552.                 //     $sslimageType = "oldkakunin";
  553.                 //     $file_headers = @get_headers($img);
  554.                 //     if($file_headers[0] != 'HTTP/1.1 403 Forbidden' or strpos( $file_headers[0],"OK" )){
  555.                 //         list($width, $height) = @getimagesize($img);
  556.                 //     }
  557.                 // }
  558.                 $shipping_infos = [];
  559.                 
  560.                 if ($v['has_sendsheet'] == 1) {
  561.                     $shipping_infos $this->OrderService->getShippingInfo($v['oh_id']);
  562.                 }
  563.                 // Get campaign discount items from OrderItems
  564.                 $campaignDiscounts $this->OrderService->getCampaignDiscountItems($v['oh_id']);
  565.                 $orderList[] = [
  566.                     'no'=> $no,
  567.                     'order'=>$v['oh_shubetsu'].'-'.$v['oh_id'],
  568.                     'date'=>$v['oh_date'],
  569.                     'payment'=>$this->mPayment[$v['oh_payment']],
  570.                     'new_kakunin_id'=>$v['new_kakunin_id'],
  571.                     'oh_id'=>$v['oh_id'],
  572.                     'oh_torikeshi'=>$v['oh_torikeshi'],
  573.                     'koguchi'=>$v['koguchi'],
  574.                     'oh_coupon_discount'=>$v['oh_coupon_discount'],
  575.                     'oh_discount'=>$v['oh_discount'],
  576.                     'oh_campaign_discount'=>$v['oh_campaign_discount'],
  577.                     'oh_campaign_description'=>$v['oh_campaign_description'],
  578.                     'campaign_discounts'=>$campaignDiscounts,
  579.                     'oh_sendcharge'=>$v['oh_sendcharge'],
  580.                     'oh_sendcharge_service'=>$v['oh_sendcharge_service'],
  581.                     'oh_daibiki'=>$v['oh_daibiki'],
  582.                     'oh_daibiki_service'=>$v['oh_daibiki_service'],
  583.                     'oh_atobarai'=>$v['oh_atobarai'],
  584.                     'oh_atobarai_service'=>$v['oh_atobarai_service'],
  585.                     'oh_sumary'=>$v['oh_sumary'],
  586.                     'oh_wrapping'=>$v['oh_wrapping'],
  587.                     'oh_zeus_linkpoint_flg'=>$v['oh_zeus_linkpoint_flg'],
  588.                     'has_sendsheet'=>$v['has_sendsheet'],
  589.                     'spr_pdate'=>$v['spr_pdate'],
  590.                     'shipping_infos'=> $shipping_infos,
  591.                 ];
  592.                 $goodsList[$no] = $this->OrderService->getMhistoryGoods($v['oh_id']);
  593.                 $no $no-1;
  594.             }
  595.         }
  596.         if(count($goodsList) > 0){
  597.             $this->checkOutOfStock($goodsListfalse);
  598.         }
  599.         // ページング
  600.         $orderCnt count($History);
  601.         $page $request->query->get('page'1);     // ?pageの指定がない場合は1ページ目とする
  602.         $itemsPerPage=5;
  603.         $max_paging_links 10;
  604.         if ($this->mobileDetector->isMobile()) {
  605.             $max_paging_links 4;
  606.         }
  607.         $pager LmHelper::paging($page$orderList$itemsPerPage$max_paging_links);
  608.         $page_offset $pager['page_offset'];
  609.         $orderList array_slice($orderList$page_offset$itemsPerPage);
  610.         // 画像の処理は重いため、ページング処理後のデータ分のみ処理
  611.         $orderList array_map(function ($order) use ($imageService) {
  612.             //
  613.             $sslimageType ImageService::IMAGE_TYPE_KAKUNIN;
  614.             if (!list($width$height) = $imageService->getImageSizeById($order['oh_id'], $sslimageType)) {
  615.                 //
  616.                 $sslimageType ImageService::IMAGE_TYPE_KAKUNIN_OLD;
  617.                 list($width$height) = $imageService->getImageSizeById($order['oh_id'], $sslimageType);
  618.             }
  619.             //
  620.             return array_merge($order, [
  621.                 'kakuninImgW'=>$width,
  622.                 'kakuninImgH'=>$height,
  623.                 'sslimageType'=>$sslimageType,
  624.             ]);
  625.         }, $orderList);
  626.         $pager['anKaishi'] = $pager['total_count']-$page_offset;
  627.         $anOwari $pager['anKaishi'] - $itemsPerPage +1;
  628.         if ($anOwari 1) {
  629.             $anOwari 1;
  630.         }
  631.         $pager['anOwari'] = $anOwari;
  632.         //var_dump($goodsList);
  633.         // ビュー(テンプレート)へデータを渡す
  634.         $main_h1 null;
  635.         $category_h1 null;
  636.         $h1_comment null;
  637.         $common_header_contents_all '';
  638.         $common_header_contents null;
  639.         $recentviews = [];
  640.         $custom_menu null;
  641.         $custom_frequently_searched_word null;
  642.         $data=[];
  643.         $BreadCrumbs = [
  644.             => $this->__getBreadCrumbs_MyPageTop(),
  645.         ];
  646.         $countAllOrder = [];
  647.         if ($this->mobileDetector->isMobile()) {
  648.             $countAllOrder $this->OrderService->getDispCount($lmCustomerId);
  649.         }
  650.         return [
  651.             'lmCustomerId' => $lmCustomerId,
  652.             'lmCustomer' => $lmCustomer,
  653.             'orderCnt' => $orderCnt,
  654.             'orderList' => $orderList,
  655.             'goodsList' => $goodsList,
  656.             'mPayment' => $this->mPayment,
  657.             'mailDisp' => $mailDisp,
  658.             'memoDisp' => $memoDisp,
  659.             'pager' => $pager,
  660.             'data' => $data,
  661.             'main_h1' => $main_h1,
  662.             'category_h1' => $category_h1,
  663.             'h1_comment' => $h1_comment,
  664.             'common_header_contents_all' => $common_header_contents_all,
  665.             'common_header_contents' => $common_header_contents,
  666.             'recentviews' => $recentviews,
  667.             'custom_menu' => $custom_menu,
  668.             'custom_frequently_searched_word' => $custom_frequently_searched_word,
  669.             'BreadCrumbs' => $BreadCrumbs,
  670.             'countAllOrder' => $countAllOrder,
  671.         ];
  672.     }
  673.     /**
  674.      * マイページ / サンプル貸出し履歴
  675.      *
  676.      * @Route("/mypage/chistory/", name="mypage/chistory", methods={"GET"})
  677.      * @Template("Mypage/chistory.twig")
  678.      */
  679.     public function chistory(Request $request)
  680.     {
  681.         $Customer $this->getUser();
  682.         $lmCustomerId $Customer->getLmCustomerId();
  683.         #LMカスタマーを取得
  684.         $lmCustomer $this->CustomerService->GetLandMarkCustomerId($lmCustomerId);
  685.         // 会員のメール表示切替用
  686.         $mailDisp 0;
  687.         if (strlen($lmCustomer['customer_mail']) > 25 and isset($lmCustomer["customer_mail"]) and $lmCustomer["customer_mail"] != "" and preg_match("/@/"$lmCustomer["customer_mail"])) {
  688.             $mailDisp 1;
  689.         }
  690.         // 購入履歴一覧の取得
  691.         $orderList=[];
  692.         $goodsList=[];
  693.         if( $History $this->OrderService->getChistory($lmCustomerId) ){
  694.             $no count($History);
  695.             foreach($History as $v){
  696.                 $sendsheet $this->OrderService->getOrderByOrderIdAndCustomerId($lmCustomerId$v['oh_id']);
  697.                 $shipping_infos = [];
  698.                 
  699.                 if ($sendsheet['has_sendsheet'] == 1) {
  700.                     $shipping_infos $this->OrderService->getShippingInfo($v['oh_id']);
  701.                 }
  702.                 $orderList[] = [
  703.                     'no'=> $no,
  704.                     'order'=>$v['oh_shubetsu'].'-'.$v['oh_id'],
  705.                     'date'=>$v['oh_date'],
  706.                     'oh_id'=>$v['oh_id'],
  707.                     'oh_catalog_id'=>$v['oh_catalog_id'],
  708.                     'order_catalog_list' => $v['order_catalog_list'],
  709.                     'oh_type'=>$v['oh_type'],
  710.                     'has_sendsheet'=>$sendsheet['has_sendsheet'],
  711.                     'spr_pdate'=>$sendsheet['spr_pdate'],
  712.                     'shipping_infos'=> $shipping_infos,
  713.                 ];
  714.                 $catalogList = [];
  715.                 $catalog null;
  716.                 if(!is_null($v['order_catalog_list']) and !empty($v['order_catalog_list'])){
  717.                     // 昔の希望カタログリスト
  718.                     $catalog $v['order_catalog_list'];
  719.                 }elseif(!is_null($v['oh_catalog_id']) and !empty($v['oh_catalog_id'])){
  720.                     // 現在の希望カタログリスト
  721.                     $tmp $this->OrderService->getChistoryCatalog($v['oh_catalog_id']);
  722.                     foreach($tmp as $data){
  723.                         $catalogList[] = $data['catalog_title'];
  724.                     }
  725.                     $catalogTitles implode("\n",$catalogList);
  726.                     $catalog $catalogTitles;
  727.                 }
  728.                 // サンプル希望商品
  729.                 $goods $this->OrderService->getChistoryGoods($v['oh_id']);
  730.                 if ($this->mobileDetector->isMobile()) {
  731.                     $goods $this->OrderService->formatGoodsForSP($v['oh_id'], $goods);
  732.                 }
  733.                 $goodsList[$no] =[
  734.                     'catalog_title' => $catalog,
  735.                     'goods' => $goods,
  736.                 ];
  737.                 $no $no-1;
  738.             }
  739.         }
  740.         $orderCnt count($orderList);
  741.         // ページング
  742.         $orderCnt count($History);
  743.         $page $request->query->get('page'1);     // ?pageの指定がない場合は1ページ目とする
  744.         $itemsPerPage=10;
  745.         $pager LmHelper::paging($page$orderList$itemsPerPage);
  746.         $page_offset $pager['page_offset'];
  747.         $orderList array_slice($orderList$page_offset$itemsPerPage);
  748.         $pager['anKaishi'] = $pager['total_count']-$page_offset;
  749.         $anOwari $pager['anKaishi'] - $itemsPerPage +1;
  750.         if ($anOwari 1) {
  751.             $anOwari 1;
  752.         }
  753.         $pager['anOwari'] = $anOwari;
  754.         $main_h1 null;
  755.         $category_h1 null;
  756.         $h1_comment null;
  757.         $common_header_contents_all '';
  758.         $common_header_contents null;
  759.         $recentviews = [];
  760.         $custom_menu null;
  761.         $custom_frequently_searched_word null;
  762.         $data=[];
  763.         $BreadCrumbs = [
  764.             => $this->__getBreadCrumbs_MyPageTop(),
  765.         ];
  766.         // ビュー(テンプレート)へデータを渡す
  767.         return [
  768.             'lmCustomerId' => $lmCustomerId,
  769.             'lmCustomer' => $lmCustomer,
  770.             'orderCnt' => $orderCnt,
  771.             'orderList' => $orderList,
  772.             'goodsList' => $goodsList,
  773.             'mailDisp' => $mailDisp,
  774.             'mailDisp' => $mailDisp,
  775.             'pager' => $pager,
  776.             'data' => $data,
  777.             'main_h1' => $main_h1,
  778.             'category_h1' => $category_h1,
  779.             'h1_comment' => $h1_comment,
  780.             'common_header_contents_all' => $common_header_contents_all,
  781.             'common_header_contents' => $common_header_contents,
  782.             'recentviews' => $recentviews,
  783.             'custom_menu' => $custom_menu,
  784.             'custom_frequently_searched_word' => $custom_frequently_searched_word,
  785.             'BreadCrumbs' => $BreadCrumbs,
  786.         ];
  787.     }
  788.     /**
  789.      * 納品書の表示
  790.      * @Route("/mypage/nouhinsho", name="nouhinsho", methods={"GET", "POST"})
  791.      * @Template("Mypage/nouhinsho.twig")
  792.      */
  793.     public function nouhinsho(Request $request)
  794.     {
  795.        //顧客情報取得
  796.         $Customer $this->getUser();
  797.         $lmCustomerId $Customer->getLmCustomerId();
  798.         $dirPath "backoffice-data/paper_data/nouhinsho_data/";
  799.         $s3 = new FileStoreService(env('S3_LM_DOC'), $dirPath);
  800.         $orderId $request->query->get('id');
  801.         $code md5(serialize($orderId));
  802.         $params = [
  803.             'dcl_type' => 'deliverynote',
  804.             'dcl_oh' => $orderId,
  805.             'dcl_customer' => $lmCustomerId,
  806.             'dcl_code' => $code,
  807.             'dcl_cdate' => date('Y-m-d H:i:s'),
  808.         ];
  809.         $message "ダウンロードエラー";
  810.         $order $this->OrderService->getOrderByOrderIdAndCustomerId($lmCustomerId$orderId);
  811.         if (!$order['oh_id']) {
  812.             return [
  813.                 'msg' => $message,
  814.             ];
  815.         }
  816.         if (!$order['has_sendsheet']) {
  817.             return [
  818.                 'msg' => 'この注文は納品書を発行していません。',
  819.             ];
  820.         }
  821.         //DB(document_create_list_table)へデータ追加 & insertデータID取得
  822.         $newId $this->OrderService->insertDocumentCreateList($params);
  823.         if($newId){
  824.             //backoffice側でデータ作成=>s3へアップ
  825.             $backURL=$this->eccubeConfig['S_BACK_URL'];
  826.             $certFilename=$this->eccubeConfig['S_BACK_CERT_FILENAME'];
  827.             $backURL=str_replace("backoffice","",$backURL);
  828.             $url="{$backURL}/getfrompc/document_download.php";
  829.             //POSTデータを作成
  830.             $params = array(
  831.                 "ID"        => $newId,
  832.                 "OH"        => $orderId,
  833.                 "CODE"        => $code,
  834.             );
  835.             $curl curl_init();
  836.             curl_setopt($curlCURLOPT_URL$url);
  837.             curl_setopt($curlCURLOPT_RETURNTRANSFERtrue);
  838.             curl_setopt($curlCURLOPT_POSTtrue);
  839.             curl_setopt($curlCURLOPT_POSTFIELDS$params);
  840.             if (!empty($certFilename)) {
  841.                 curl_setopt($curlCURLOPT_SSLCERT$certFilename);
  842.                 curl_setopt($curlCURLOPT_USERAGENT'curl/7.52.1');
  843.             }
  844.             if($response curl_exec($curl)){
  845.                 $line explode(":",$response);
  846.                 if($line[0] = "OK"){
  847.                     //ファイル名
  848.                     $Filename $line[1];
  849.                     echo $Filename;
  850.                     if($s3->isObjectExists($Filename) !== false){
  851.                         $content=env('S3_LM_DOC_PATH') ."/".$dirPath.$Filename;
  852.                         header('Content-Type: application/pdf');
  853.                         readfile($content);
  854.                         exit;
  855.                     }
  856.                 }
  857.             }
  858.             curl_close($curl);
  859.         }
  860.         return [
  861.             'msg' => $message,
  862.         ];
  863.     }
  864.     /**
  865.      * マイページ / 確認書
  866.      *
  867.      * @Route("/mypage/kakuninsho", name="mypage/kakuninsho", methods={"GET"})
  868.      * @Template("Mypage/kakuninsho.twig")
  869.      */
  870.     public function kakuninsho(Request $request)
  871.     {
  872.         $orderId $request->query->get('id');
  873.         $Customer $this->getUser();
  874.         $lmCustomerId $Customer->getLmCustomerId();
  875.         $order $this->OrderService->getOrderByOrderIdAndCustomerId($lmCustomerId$orderId);
  876.         $campaignDiscounts $this->OrderService->getCampaignDiscountItems($orderId);
  877.         if (empty($order)) {
  878.             throw new NotFoundHttpException();
  879.         }
  880.         #LMカスタマーを取得
  881.         $lmCustomer $this->CustomerService->GetLandMarkCustomerId($lmCustomerId);
  882.         list($allData,$kakuninData) = $this->OrderService->getKakuninshoLibrary($orderId);
  883.         list($detailDisplay,$detailData,$goods_cnt) = $this->OrderService->getKakuninshoLibraryGoods($orderId);
  884.         // 名入れ加工の検索
  885.         list($insObj1,$insObj2,$insObj3,$dispArray) = $this->OrderService->getKakuninNaire($orderId);
  886.         // 裾上げ商品
  887.         $susoageGoods $this->OrderService->getSusoageGoods($orderId);
  888.         $today date('Y年m月d日');
  889.         $kakuninDate "";
  890.         $kakuninDate $kakuninData['new_kakunin_date']."(" $this->DOW[$kakuninData['new_kakunin_date_week']] . ")";
  891.         //asort( $detailData );
  892.         reset$detailData );
  893.         $kakuninImg "";
  894.         $img="/kanri_img/images/new_kakunin_img/" $orderId ".jpg";
  895.         $file_headers = @get_headers($img);
  896.         if(
  897.             isset($file_headers[0])
  898.             && ($file_headers[0] != 'HTTP/1.1 403 Forbidden' or strpos$file_headers[0],"OK" ))
  899.         ){
  900.             $kakuninImg "/sslimage?type=kakunin&id=" $orderId "&x=240";
  901.         } else if(!empty($susoageGoods)){
  902.             $kakuninImg "/kanri_img/images/hanger/susoage.jpg";
  903.         } else {
  904.             $kakuninImg "/images/mypage/blank.gif";
  905.         }
  906.         $BreadCrumbs = [
  907.             => $this->__getBreadCrumbs_MyPageTop(),
  908.         ];
  909.         // ビュー(テンプレート)へデータを渡す
  910.         return [
  911.             'lmCustomerId' => $lmCustomerId,
  912.             'lmCustomer' => $lmCustomer,
  913.             'data' => $kakuninData,
  914.             'kakuninAllData' => $allData,
  915.             'kakuninDetailDisplay' => $detailDisplay,
  916.             'kakuninDetailData' => $detailData,
  917.             'kakuninDate' => $kakuninDate,
  918.             'insObj1' => $insObj1,
  919.             'insObj2' => $insObj2,
  920.             'insObj3' => $insObj3,
  921.             'dispArray' => $dispArray,
  922.             'goods_cnt' => $goods_cnt,
  923.             'susoageGoods' => $susoageGoods,
  924.             'today' => $today,
  925.             'orderId' => $orderId,
  926.             'kakuninImg' => $kakuninImg,
  927.             'BreadCrumbs' => $BreadCrumbs,
  928.             'campaignDiscounts' => $campaignDiscounts,
  929.         ];
  930.     }
  931.     /**
  932.      * マイページトップのパンくず定義
  933.      * @return Array マイページトップのパンくず href, label
  934.      */
  935.     private function __getBreadCrumbs_MyPageTop()
  936.     {
  937.         return [
  938.             'href' => $this->generateUrl('mypage'),
  939.             'label' => $this->CommonService->GetPagename('mypage'),
  940.         ];
  941.     }
  942.     /**
  943.      * ログイン画面.
  944.      *
  945.      * @Route("/mypage/login", name="mypage_login", methods={"GET", "POST"})
  946.      * @Template("Mypage/login.twig")
  947.      */
  948.     public function login(Request $requestAuthenticationUtils $utils)
  949.     {
  950.         if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
  951.             log_info('認証済のためログイン処理をスキップ');
  952.             return $this->redirectToRoute('mypage');
  953.         }
  954.         /* @var $form \Symfony\Component\Form\FormInterface */
  955.         $builder $this->formFactory
  956.             ->createNamedBuilder(''CustomerLoginType::class);
  957.         $builder->get('login_memory')->setData((bool) $request->getSession()->get('_security.login_memory'));
  958.         if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
  959.             $Customer $this->getUser();
  960.             if ($Customer instanceof Customer) {
  961.                 $builder->get('login_email')
  962.                     ->setData($Customer->getEmail());
  963.             }
  964.         }
  965.         $event = new EventArgs(
  966.             [
  967.                 'builder' => $builder,
  968.             ],
  969.             $request
  970.         );
  971.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_MYPAGE_MYPAGE_LOGIN_INITIALIZE);
  972.         $form $builder->getForm();
  973.         $main_h1 null;
  974.         $category_h1 null;
  975.         $h1_comment null;
  976.         $common_header_contents_all '';
  977.         $common_header_contents null;
  978.         $recentviews = [];
  979.         $custom_menu null;
  980.         $custom_frequently_searched_word null;
  981.         $data=[];
  982.         return [
  983.             'error' => $utils->getLastAuthenticationError(),
  984.             'form' => $form->createView(),
  985.             'data' => $data,
  986.             'main_h1' => $main_h1,
  987.             'category_h1' => $category_h1,
  988.             'h1_comment' => $h1_comment,
  989.             'common_header_contents_all' => $common_header_contents_all,
  990.             'common_header_contents' => $common_header_contents,
  991.             'recentviews' => $recentviews,
  992.             'custom_menu' => $custom_menu,
  993.             'custom_frequently_searched_word' => $custom_frequently_searched_word,
  994.             'BreadCrumbs' => [],
  995.         ];
  996.     }
  997.     /**
  998.      * Get coupon type based on target
  999.      * 
  1000.      * @param string $target
  1001.      * @return string
  1002.      */
  1003.     private function getCouponType($target$lmCustomer)
  1004.     {
  1005.         switch (true) {
  1006.             case $target === '未購入者':
  1007.                 return 'first_purchase'// 1. 初回限定クーポン
  1008.             case $target === 'メルマガ購読者全員':
  1009.                 return 'newsletter'// 2. メルマガ購読者用クーポン
  1010.             case $target === 'お客様の声に回答したお客様(写真無)':
  1011.                 return 'customer_feedback_without_photo'// 3. お客様の声に回答したお客様(写真無)
  1012.             case $target === 'お客様の声に回答したお客様(写真有)':
  1013.                 return 'customer_feedback_with_photo'// 4. お客様の声に回答したお客様(写真有)
  1014.             case $target === '全員':
  1015.                 return 'for_all_customer'// 5. 全員
  1016.             case preg_match('/^スポットメール:\d+$/u'$target):
  1017.                 return 'spot_mail'// 6. スポットメール
  1018.             default:
  1019.                 return 'general';
  1020.         }
  1021.     }
  1022.     /**
  1023.      * Get coupon status based on expiration date
  1024.      * 
  1025.      * @param string $expiresAt
  1026.      * @return string
  1027.      */
  1028.     private function getCouponStatus($expiresAt)
  1029.     {
  1030.         if (!$expiresAt) {
  1031.             return 'unknown';
  1032.         }
  1033.         
  1034.         $expiryDate = new \DateTime($expiresAt);
  1035.         $now = new \DateTime();
  1036.         $diff $now->diff($expiryDate);
  1037.         
  1038.         if ($expiryDate $now) {
  1039.             return 'expired';
  1040.         } elseif ($diff->days <= 3) {
  1041.             return 'expiring_soon';
  1042.         } else {
  1043.             return 'active';
  1044.         }
  1045.     }
  1046. }