app/Customize/Controller/EntryControllerExtends.php line 237

Open in your IDE?
  1. <?php
  2. namespace Customize\Controller;
  3. use Customize\Repository\CouponRepository;
  4. use Customize\Service\CouponCodeGenerator;
  5. use Customize\Service\ReferralLinkGenerator;
  6. use Eccube\Controller\EntryController;
  7. use Plugin\ECCUBE4LineLoginIntegration42\Controller\LineLoginIntegrationController;
  8. use Eccube\Entity\BaseInfo;
  9. use Eccube\Entity\Master\CustomerStatus;
  10. use Eccube\Event\EccubeEvents;
  11. use Eccube\Event\EventArgs;
  12. use Eccube\Form\Type\Front\EntryType;
  13. use Eccube\Repository\BaseInfoRepository;
  14. use Eccube\Repository\CustomerRepository;
  15. use Eccube\Repository\Master\CustomerStatusRepository;
  16. use Eccube\Repository\PageRepository;
  17. use Eccube\Service\CartService;
  18. use Eccube\Service\MailService;
  19. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  20. use Symfony\Component\HttpFoundation\Request;
  21. use Symfony\Component\HttpKernel\Exception as HttpException;
  22. use Symfony\Component\Routing\Annotation\Route;
  23. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  24. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  25. use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
  26. use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
  27. use Symfony\Component\Validator\Constraints as Assert;
  28. use Symfony\Component\Validator\Validator\ValidatorInterface;
  29. use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
  30. use Symfony\Component\Security\Http\SecurityEvents;
  31. use Symfony\Component\HttpFoundation\RedirectResponse;
  32. use Symfony\Component\Form\FormError;
  33. class EntryControllerExtends extends EntryController
  34. {
  35.     /**
  36.      * @var CustomerStatusRepository
  37.      */
  38.     protected $customerStatusRepository;
  39.     /**
  40.      * @var ValidatorInterface
  41.      */
  42.     protected $recursiveValidator;
  43.     /**
  44.      * @var MailService
  45.      */
  46.     protected $mailService;
  47.     /**
  48.      * @var BaseInfo
  49.      */
  50.     protected $BaseInfo;
  51.     /**
  52.      * @var CustomerRepository
  53.      */
  54.     protected $customerRepository;
  55.     /**
  56.      * @var EncoderFactoryInterface
  57.      */
  58.     protected $encoderFactory;
  59.     /**
  60.      * @var TokenStorageInterface
  61.      */
  62.     protected $tokenStorage;
  63.     /**
  64.      * @var \Eccube\Service\CartService
  65.      */
  66.     protected $cartService;
  67.     /**
  68.      * @var PageRepository
  69.      */
  70.     protected $pageRepository;
  71.     /**
  72.      * @var CouponRepository
  73.      */
  74.     protected $couponRepository;
  75.     /**
  76.      * @var CouponCodeGenerator 
  77.      */
  78.     private $couponCodeGenerator;
  79.     
  80.     /**
  81.      * @var ReferralLinkGenerator
  82.      */
  83.     private $referralCodeGenerator;
  84.     /**
  85.      * EntryController constructor.
  86.      *
  87.      * @param CartService $cartService
  88.      * @param CustomerStatusRepository $customerStatusRepository
  89.      * @param MailService $mailService
  90.      * @param BaseInfoRepository $baseInfoRepository
  91.      * @param CustomerRepository $customerRepository
  92.      * @param EncoderFactoryInterface $encoderFactory
  93.      * @param ValidatorInterface $validatorInterface
  94.      * @param TokenStorageInterface $tokenStorage
  95.      * @param PageRepository $pageRepository
  96.      * @param CouponRepository $couponRepository
  97.      * @param CouponCodeGenerator $couponCodeGenerator
  98.      * @param ReferralLinkGenerator $referralCodeGenerator
  99.      */
  100.     public function __construct(
  101.         CartService $cartService,
  102.         CustomerStatusRepository $customerStatusRepository,
  103.         MailService $mailService,
  104.         BaseInfoRepository $baseInfoRepository,
  105.         CustomerRepository $customerRepository,
  106.         EncoderFactoryInterface $encoderFactory,
  107.         ValidatorInterface $validatorInterface,
  108.         TokenStorageInterface $tokenStorage,
  109.         PageRepository $pageRepository,
  110.         CouponRepository $couponRepository,
  111.         CouponCodeGenerator $couponCodeGenerator,
  112.         ReferralLinkGenerator $referralCodeGenerator
  113.         
  114.     ) {
  115.         $this->customerStatusRepository $customerStatusRepository;
  116.         $this->mailService $mailService;
  117.         $this->BaseInfo $baseInfoRepository->get();
  118.         $this->customerRepository $customerRepository;
  119.         $this->encoderFactory $encoderFactory;
  120.         $this->recursiveValidator $validatorInterface;
  121.         $this->tokenStorage $tokenStorage;
  122.         $this->cartService $cartService;
  123.         $this->pageRepository $pageRepository;
  124.         $this->couponRepository $couponRepository;
  125.         $this->couponCodeGenerator $couponCodeGenerator;
  126.         $this->referralCodeGenerator $referralCodeGenerator;
  127.     }
  128.     /**
  129.      * 会員登録前.
  130.      *
  131.      * @Route("/entry/before", name="entry_before", methods={"GET"})
  132.      * @Template("Entry/before.twig")
  133.      */
  134.     public function before(Request $request)
  135.     {
  136.         $sendto $request->query->get('sendto'); // detail / list / homepage 
  137.         $param $request->query->get('param'); // detail=商品ID / list=キーワード
  138.         $referrer_code $request->query->get('rc'); // 紹介コード
  139.         // ログイン済みかどうかを判定する →ログイン済みの場合はリダイレクトする
  140.         $Customer $this->getUser();
  141.         if($Customer){
  142.             // パラメータに合わせてリダイレクトする
  143.             
  144.             // 商品詳細/商品一覧/TOPのいずれかが指定されていればリダイレクトする
  145.             if($sendto == 'detail'){
  146.                 $url $this->generateUrl('product_detail', ['id' => $param]);
  147.                 return new RedirectResponse($url);
  148.             } else if($sendto == 'list'){
  149.                 $url $this->generateUrl('product_list', ['name' => $param], UrlGeneratorInterface::RELATIVE_PATH);
  150.                 return new RedirectResponse($url);
  151.             } else if($sendto == 'homepage'){
  152.                 $url $this->generateUrl('homepage');
  153.                 return new RedirectResponse($url);
  154.             }
  155.         }
  156.         // 会員登録後のリダイレクト先が設定されていればSessionに格納する
  157.         if($sendto != null){
  158.             $this->session->set('sendto'$sendto);
  159.         }
  160.         if($param != null){
  161.             $this->session->set('param'$param);
  162.         }
  163.         if($referrer_code != null){
  164.             $this->session->set('entry.referrer.code'$referrer_code);
  165.             // 不正な紹介リンクではないかチェック
  166.             try {
  167.                 $referralCode self::getReferrerCode($request);
  168.                 if ($referralCode != null) {
  169.                     $this->referralCodeGenerator->decode(
  170.                         (string) $referralCode
  171.                     );
  172.                 }
  173.             } catch (\InvalidArgumentException $ex) {
  174.                 $this->session->remove('entry.referrer.code');
  175.                 return [
  176.                     "invalidCode" => true
  177.                 ];
  178.             }
  179.         }
  180.         
  181.         // LPから来たかどうかを判定しSessionに格納する
  182.         $fromZitanLp $request->query->get('fromZitanLp');
  183.         if($fromZitanLp != null && $fromZitanLp == 1){
  184.             $this->session->set('fromZitanLp'$fromZitanLp);
  185.         }
  186.         $fromSpotMenuLp $request->query->get('fromSpotMenuLp');
  187.         if($fromSpotMenuLp != null && $fromSpotMenuLp == 1){
  188.             $this->session->set('fromSpotMenuLp'$fromSpotMenuLp);
  189.         }
  190.         $fromOriginalMenuLp $request->query->get('fromOriginalMenuLp');
  191.         if($fromOriginalMenuLp != null && $fromOriginalMenuLp == 1){
  192.             $this->session->set('fromOriginalMenuLp'$fromOriginalMenuLp);
  193.         }
  194.         $fromTrigalCp $request->query->get('fromTrigalCp');
  195.         if($fromTrigalCp != null && $fromTrigalCp == 1){
  196.             $this->session->set('fromTrigalCp'$fromTrigalCp);
  197.         }
  198.         $fromNewOpenRestoLp $request->query->get('fromNewOpenRestoLp');
  199.         if($fromNewOpenRestoLp != null && $fromNewOpenRestoLp == 1){
  200.             $this->session->set('fromNewOpenRestoLp'$fromNewOpenRestoLp);
  201.         }      
  202.         return ["invalidCode" => false];
  203.     }
  204.     /**
  205.      * 会員登録画面.
  206.      *
  207.      * @Route("/entry", name="entry", methods={"GET", "POST"})
  208.      * @Route("/entry", name="entry_confirm", methods={"GET", "POST"})
  209.      * @Template("Entry/index.twig")
  210.      */
  211.     public function index(Request $request)
  212.     {
  213.         // Line経由で遷移しているかどうかを判定する
  214.         $lineUserId $this->session->get(LineLoginIntegrationController::PLUGIN_LINE_LOGIN_INTEGRATION_SSO_USERID);
  215.         $isFromLine false;
  216.         $dummyPass $this->eccubeConfig['eccube_default_password'];
  217.         if($lineUserId){
  218.             $isFromLine true;
  219.         }
  220.         // LPから来たかどうかを判定しSessionにパラメータ設定する
  221.         $fromZitanLp $request->query->get('fromZitanLp');
  222.         if($fromZitanLp != null && $fromZitanLp == 1){
  223.             $this->session->set('fromZitanLp'$fromZitanLp);
  224.         }
  225.         $fromSpotMenuLp $request->query->get('fromSpotMenuLp');
  226.         if($fromSpotMenuLp != null && $fromSpotMenuLp == 1){
  227.             $this->session->set('fromSpotMenuLp'$fromSpotMenuLp);
  228.         }
  229.         $fromOriginalMenuLp $request->query->get('fromOriginalMenuLp');
  230.         if($fromOriginalMenuLp != null && $fromOriginalMenuLp == 1){
  231.             $this->session->set('fromOriginalMenuLp'$fromOriginalMenuLp);
  232.         }
  233.         $fromTrigalCp $request->query->get('fromTrigalCp');
  234.         if($fromTrigalCp != null && $fromTrigalCp == 1){
  235.             $this->session->set('fromTrigalCp'$fromTrigalCp);
  236.         }
  237.         $fromNewOpenRestoLp $request->query->get('fromNewOpenRestoLp');
  238.         if($fromNewOpenRestoLp != null && $fromNewOpenRestoLp == 1){
  239.             $this->session->set('fromNewOpenRestoLp'$fromNewOpenRestoLp);
  240.         }
  241.         // /entry?c=xxxで来た紹介コードを初回GETでデコード→referrer_idをセッションentry.referralに保持。失敗時はセッションをクリアしつつエラーフラッシュ。
  242.         $referralCode self::getReferrerCode($request);
  243.         if ($referralCode != null) {
  244.             $referrer_id $this->referralCodeGenerator->decode(
  245.                 (string) $referralCode
  246.             );
  247.             $this->session->set('entry.referral'$referrer_id);
  248.         }
  249.         if ($this->isGranted('ROLE_USER')) {
  250.             log_info('認証済のためログイン処理をスキップ');
  251.             return $this->redirectToRoute('mypage');
  252.         }
  253.         /** @var $Customer \Eccube\Entity\Customer */
  254.         $Customer $this->customerRepository->newCustomer();
  255.         /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
  256.         $builder $this->formFactory->createBuilder(EntryType::class, $Customer);
  257.         $event = new EventArgs(
  258.             [
  259.                 'builder' => $builder,
  260.                 'Customer' => $Customer,
  261.             ],
  262.             $request
  263.         );
  264.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_ENTRY_INDEX_INITIALIZE);
  265.         /* @var $form \Symfony\Component\Form\FormInterface */
  266.         $form $builder->getForm();
  267.         $form->handleRequest($request);
  268.         if ($form->isSubmitted() && $form->isValid()) {
  269.             switch ($request->get('mode')) {
  270.                 case 'confirm':
  271.                     log_info('会員登録確認開始');
  272.                     log_info('会員登録確認完了');
  273.                     return $this->render(
  274.                         'Entry/confirm.twig',
  275.                         [
  276.                             'form' => $form->createView(),
  277.                             'Page' => $this->pageRepository->getPageByRoute('entry_confirm'),
  278.                             'isFromLine' => $isFromLine,
  279.                         ]
  280.                     );
  281.                 case 'complete':
  282.                     log_info('会員登録開始');
  283.                     $encoder $this->encoderFactory->getEncoder($Customer);
  284.                     $salt $encoder->createSalt();
  285.                     $password $encoder->encodePassword($Customer->getPlainPassword(), $salt);
  286.                     $secretKey $this->customerRepository->getUniqueSecretKey();
  287.                     // 紹介リンクからの登録である場合
  288.                     // 紹介者のコードが上限を超えている場合にはエラーを返す
  289.                     $referral $this->session->get('entry.referral');
  290.                     if ($referral) {
  291.                         $Referrer $this->customerRepository->find($referral['id'] ?? 0);
  292.                         if (!$Referrer) {
  293.                             $form->addError(new FormError('紹介コードが無効です。'));
  294.                         } else {
  295.                             $limit  = (int) $this->eccubeConfig['max_issue_count_refer_friend'];
  296.                             $issued $this->couponRepository->getCountForIssuedReferralCoupon($Referrer);
  297.                             if ($issued >= $limit) {
  298.                                 $form->addError(new FormError('紹介者が紹介できる友達の上限を超えました'));
  299.                             } else {
  300.                                 $Customer->setReferrer($Referrer);
  301.                             }
  302.                         }
  303.                         if ($form->getErrors(true)->count() > 0) {
  304.                             // 必要なら紹介情報は破棄
  305.                             $this->session->remove('entry.referral');
  306.                             return $this->render('Entry/confirm.twig', [
  307.                                 'form'        => $form->createView(),
  308.                                 'Page'        => $this->pageRepository->getPageByRoute('entry_confirm'),
  309.                                 'isFromLine'  => $isFromLine,
  310.                             ]);
  311.                         }
  312.                     }
  313.                     $Customer
  314.                         ->setSalt($salt)
  315.                         ->setPassword($password)
  316.                         ->setSecretKey($secretKey)
  317.                         ->setPoint(0);
  318.                     $this->entityManager->persist($Customer);
  319.                     $this->entityManager->flush();
  320.                     // 紹介コードで登録を行った場合
  321.                     if ($Customer->getReferrer()) {
  322.                         $couponCode $this->couponCodeGenerator->generateReferralFriendCode(false);
  323.                         // 
  324.                         $coupon $this->couponRepository->issueReferralCoupons($Customer->getReferrer(), $Customer$couponCodefalse);
  325.                         if($coupon != null && $Customer != null) {
  326.                             $this->couponRepository->attachCouponToCustomer($coupon$Customer);
  327.                         }
  328.                     }
  329.                     log_info('会員登録完了');
  330.                     $event = new EventArgs(
  331.                         [
  332.                             'form' => $form,
  333.                             'Customer' => $Customer,
  334.                         ],
  335.                         $request
  336.                     );
  337.                     $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_ENTRY_INDEX_COMPLETE);
  338.                     $activateFlg $this->BaseInfo->isOptionCustomerActivate();
  339.                     // 仮会員設定が有効な場合は、確認メールを送信し完了画面表示.
  340.                     if ($activateFlg) {
  341.                         $activateUrl $this->generateUrl('entry_activate', ['secret_key' => $Customer->getSecretKey()], UrlGeneratorInterface::ABSOLUTE_URL);
  342.                         // メール送信
  343.                         $this->mailService->sendCustomerConfirmMail($Customer$activateUrl);
  344.                         if ($event->hasResponse()) {
  345.                             return $event->getResponse();   
  346.                         }
  347.                         log_info('仮会員登録完了画面へリダイレクト');
  348.                         return $this->redirectToRoute('entry_complete');
  349.                     } else {
  350.                         // 仮会員設定が無効な場合は、会員登録を完了させる.
  351.                         $qtyInCart $this->entryActivate($request$Customer->getSecretKey());
  352.                 
  353.                         // カートに商品が入っていれば購入確認画面に遷移する
  354.                         if ($qtyInCart) {
  355.                             return $this->redirectToRoute('shopping', [
  356.                                 'secret_key' => $Customer->getSecretKey(),
  357.                                 'qtyInCart' => $qtyInCart,
  358.                             ]);
  359.                         }
  360.                         // URLを変更するため完了画面にリダイレクト
  361.                         return $this->redirectToRoute('entry_activate', [
  362.                             'secret_key' => $Customer->getSecretKey(),
  363.                             'qtyInCart' => $qtyInCart,
  364.                         ]);
  365.                     }
  366.             }
  367.         }
  368.         return [
  369.             'form' => $form->createView(),
  370.             'isFromLine' => $isFromLine,
  371.             'dummyPass' => $dummyPass,
  372.         ];
  373.     }
  374.     /**
  375.      * 会員登録完了画面.
  376.      *
  377.      * @Route("/entry/complete", name="entry_complete", methods={"GET"})
  378.      * @Template("Entry/complete.twig")
  379.      */
  380.     public function complete()
  381.     {
  382.         return [];
  383.     }
  384.     /**
  385.      * 会員のアクティベート(本会員化)を行う.
  386.      *
  387.      * @Route("/entry/activate/{secret_key}/{qtyInCart}", name="entry_activate", methods={"GET"})
  388.      * @Template("Entry/activate.twig")
  389.      */
  390.     public function activate(Request $request$secret_key$qtyInCart null)
  391.     {
  392.         $errors $this->recursiveValidator->validate(
  393.             $secret_key,
  394.             [
  395.                 new Assert\NotBlank(),
  396.                 new Assert\Regex(
  397.                     [
  398.                         'pattern' => '/^[a-zA-Z0-9]+$/',
  399.                     ]
  400.                 ),
  401.             ]
  402.         );
  403.         if (!$this->session->has('eccube.login.target.path')) {
  404.             $this->setLoginTargetPath($this->generateUrl('mypage', [], UrlGeneratorInterface::ABSOLUTE_URL));
  405.         }
  406.         if (!is_null($qtyInCart)) {
  407.             // Line連携ログイン稼動か
  408.             $Customer $this->getUser();
  409.             $lineLoginIntegration $Customer->getLineLoginIntegration();
  410.             $isLineRelatedUser false;
  411.             if($lineLoginIntegration != null){
  412.                 $isLineRelatedUser true;
  413.             }
  414.             // 紹介リンクからの登録か
  415.             $isReferralUser false;
  416.             if ($Customer->getReferrer() != null) {
  417.                 $isReferralUser true;
  418.             }
  419.             // 遷移先ページが指定されていれば先にリダイレクト処理する
  420.             $sendto $this->session->get('sendto');
  421.             $param $this->session->get('param');
  422.             // 商品詳細/商品一覧/TOPのいずれかが指定されていればリダイレクトする
  423.             if($sendto == 'detail'){
  424.                 $url $this->generateUrl('product_detail', ['id' => $param]);
  425.                 return new RedirectResponse($url);
  426.             } else if($sendto == 'list'){
  427.                 $url $this->generateUrl('product_list', ['name' => $param], UrlGeneratorInterface::RELATIVE_PATH);
  428.                 return new RedirectResponse($url);
  429.             } else if($sendto == 'homepage'){
  430.                 $url $this->generateUrl('homepage');
  431.                 return new RedirectResponse($url);
  432.             }
  433.             // どのLPからの遷移か特定するパラメータ
  434.             $fromZitanLp $this->session->get('fromZitanLp');
  435.             $fromSpotMenuLp $this->session->get('fromSpotMenuLp');
  436.             $fromOriginalMenuLp $this->session->get('fromOriginalMenuLp');
  437.             $fromTrigalCp $this->session->get('fromTrigalCp');
  438.             $fromNewOpenRestoLp $this->session->get('fromNewOpenRestoLp');
  439.             return [
  440.                 'qtyInCart' => $qtyInCart,
  441.                 'isLineRelatedUser' => $isLineRelatedUser,
  442.                 'isReferralUser' => $isReferralUser,
  443.                 'fromZitanLp' => $fromZitanLp,
  444.                 'fromSpotMenuLp' => $fromSpotMenuLp,
  445.                 'fromOriginalMenuLp' => $fromOriginalMenuLp,
  446.                 'fromTrigalCp' => $fromTrigalCp,
  447.                 'fromNewOpenRestoLp' => $fromNewOpenRestoLp,
  448.             ];
  449.         } elseif ($request->getMethod() === 'GET' && count($errors) === 0) {
  450.             // 会員登録処理を行う
  451.             $qtyInCart $this->entryActivate($request$secret_key);
  452.             return [
  453.                 'qtyInCart' => $qtyInCart,
  454.             ];
  455.         }
  456.         throw new HttpException\NotFoundHttpException();
  457.     }
  458.     /**
  459.      * 会員登録処理を行う
  460.      *
  461.      * @param Request $request
  462.      * @param $secret_key
  463.      *
  464.      * @return \Eccube\Entity\Cart|mixed
  465.      */
  466.     private function entryActivate(Request $request$secret_key)
  467.     {
  468.         log_info('本会員登録開始');
  469.         $Customer $this->customerRepository->getProvisionalCustomerBySecretKey($secret_key);
  470.         if (is_null($Customer)) {
  471.             throw new HttpException\NotFoundHttpException();
  472.         }
  473.         $CustomerStatus $this->customerStatusRepository->find(CustomerStatus::REGULAR);
  474.         $Customer->setStatus($CustomerStatus);
  475.         $this->entityManager->persist($Customer);
  476.         $this->entityManager->flush();
  477.         log_info('本会員登録完了');
  478.         $event = new EventArgs(
  479.             [
  480.                 'Customer' => $Customer,
  481.             ],
  482.             $request
  483.         );
  484.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_ENTRY_ACTIVATE_COMPLETE);
  485.         // メール送信
  486.         $this->mailService->sendCustomerCompleteMail($Customer);
  487.         // 本会員登録してログイン状態にする
  488.         $token = new UsernamePasswordToken($Customernull'customer', array('ROLE_USER'));
  489.         $this->tokenStorage->setToken($token);
  490.         log_info('ログイン済に変更。dtb_customer.id:'.$this->getUser()->getId());
  491.         // カートのマージなどの処理
  492.         $loginEvent = new InteractiveLoginEvent($request$token);
  493.         $this->eventDispatcher->dispatch(
  494.             $loginEvent,
  495.             SecurityEvents::INTERACTIVE_LOGIN
  496.         );
  497.         // Assign session carts into customer carts
  498.         $Carts $this->cartService->getCarts();
  499.         $qtyInCart 0;
  500.         foreach ($Carts as $Cart) {
  501.             $qtyInCart += $Cart->getTotalQuantity();
  502.         }
  503.         if ($qtyInCart) {
  504.             $this->cartService->save();
  505.         }
  506.         return $qtyInCart;
  507.     }
  508.     /**
  509.      * 紹介コードを
  510.      * @param mixed $request
  511.      */
  512.     private function getReferrerCode($request) {
  513.         if($request->query->get('rc') == null){
  514.             return $this->session->get('entry.referrer.code');
  515.         } else {
  516.             return $request->query->get('rc');
  517.         }
  518.     }
  519. }