app/Plugin/ECCUBE4LineLoginIntegration42/LineLoginIntegrationEvent.php line 45

Open in your IDE?
  1. <?php
  2. namespace Plugin\ECCUBE4LineLoginIntegration42;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use Eccube\Event\EventArgs;
  5. use Eccube\Event\TemplateEvent;
  6. use Eccube\Event\EccubeEvents;
  7. use Eccube\Entity\Master\CustomerStatus;
  8. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  9. use Psr\Container\ContainerInterface;
  10. use Symfony\Component\Form\FormFactoryInterface;
  11. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  12. use Plugin\ECCUBE4LineLoginIntegration42\Controller\LineLoginIntegrationController;
  13. use Plugin\ECCUBE4LineLoginIntegration42\Controller\Admin\LineLoginIntegrationAdminController;
  14. use Plugin\ECCUBE4LineLoginIntegration42\Entity\LineLoginIntegration;
  15. use Plugin\ECCUBE4LineLoginIntegration42\Repository\LineLoginIntegrationRepository;
  16. use Plugin\ECCUBE4LineLoginIntegration42\Repository\LineLoginIntegrationSettingRepository;
  17. use Symfony\Component\Routing\RouterInterface;
  18. use Twig\Environment as Twig;
  19. use Symfony\Component\HttpFoundation\RequestStack;
  20. class LineLoginIntegrationEvent implements EventSubscriberInterface
  21. {
  22.     private $lineLoginIntegrationRepository;
  23.     private $lineLoginIntegrationSettingRepository;
  24.     private $router;
  25.     private $session;
  26.     private $entityManager;
  27.     private $formFactory;
  28.     private $twig;
  29.     public function __construct(
  30.         LineLoginIntegrationRepository $lineLoginIntegrationRepository,
  31.         LineLoginIntegrationSettingRepository $lineLoginIntegrationSettingRepository,
  32.         RequestStack $requestStack,
  33.         Twig $twig,
  34.         EntityManagerInterface $entityManager,
  35.         RouterInterface $router,
  36.         FormFactoryInterface $formFactory
  37.     ) {
  38.         $this->lineLoginIntegrationRepository $lineLoginIntegrationRepository;
  39.         $this->lineLoginIntegrationSettingRepository $lineLoginIntegrationSettingRepository;
  40.         $this->router $router;
  41.         $this->session $requestStack->getSession();
  42.         $this->entityManager $entityManager;
  43.         $this->formFactory $formFactory;
  44.         $this->twig $twig;
  45.     }
  46.     public static function getSubscribedEvents()
  47.     {
  48.         return [
  49.             'Entry/index.twig' => [
  50.                 ['onRenderEntryIndex'10],
  51.                 ['onRenderLineEntryButton', -10]
  52.             ],
  53.             EccubeEvents::FRONT_ENTRY_INDEX_COMPLETE => 'onCompleteEntry',
  54.             'Mypage/login.twig' => 'onRenderLineLoginButton',
  55.             'Mypage/change.twig' => 'onRenderMypageChange',
  56.             'Shopping/login.twig' => 'onRenderShoppingLineLoginButton',
  57.             EccubeEvents::FRONT_MYPAGE_CHANGE_INDEX_COMPLETE => 'onCompleteMypageChange',
  58.             EccubeEvents::FRONT_MYPAGE_WITHDRAW_INDEX_COMPLETE => 'onCompleteMypageWithdraw',
  59.             EccubeEvents::ADMIN_CUSTOMER_EDIT_INDEX_COMPLETE => 'onCompleteCustomerEdit',
  60.         ];
  61.     }
  62.     /**
  63.      * 新規会員登録画面の表示
  64.      * @param TemplateEvent $event
  65.      */
  66.     public function onRenderEntryIndex(TemplateEvent $event)
  67.     {
  68.         if (!$this->isLineSettingCompleted()) {
  69.             return;
  70.         }
  71.     }
  72.     /**
  73.      * 新規会員登録画面にLINEボタンを出力します
  74.      *
  75.      * @param TemplateEvent $event
  76.      */
  77.     public function onRenderLineEntryButton(TemplateEvent $event)
  78.     {
  79.         if (!$this->isLineSettingCompleted()) {
  80.             return;
  81.         }
  82.         $lineUserId $this->session->get(LineLoginIntegrationController::PLUGIN_LINE_LOGIN_INTEGRATION_SSO_USERID);
  83.         $linkUrl $this->router->generate("plugin_line_login", array(), UrlGeneratorInterface::ABSOLUTE_URL);
  84.         $imgUrl $this->router->generate("homepage", array(),
  85.                 UrlGeneratorInterface::ABSOLUTE_URL) . 'html/plugin/line_login_integration/assets/img/btn_register_base.png';
  86.         $snipet '';
  87.         // LINEボタンを表示
  88.         if (empty($lineUserId)) {
  89.             $snipet .= '<div class="btn" style=""><a href="' $linkUrl '" class="line-button"><img src="' $imgUrl '" alt="LINEで登録"></a></div>' PHP_EOL;
  90.             $snipet .= PHP_EOL;
  91.         }
  92.         // LINEにログイン済みなので登録を促す
  93.         else {
  94.             $snipet .= '<div class="col" style="margin-top:-10px; padding:10px;">LINEログイン済みです。この会員登録が完了すると、LINEでログインできるようになります。</div>';
  95.             $snipet .= PHP_EOL;
  96.         }
  97.         $search '<div class="ec-off1Grid__cell">';
  98.         $replace $search $snipet;
  99.         $source str_replace($search$replace$event->getSource());
  100.         $event->setSource($source);
  101.     }
  102.     /**
  103.      * 会員登録処理完了時のLINE連携処理
  104.      * @param EventArgs $event
  105.      */
  106.     public function onCompleteEntry(EventArgs $event)
  107.     {
  108.         if (!$this->isLineSettingCompleted()) {
  109.             return;
  110.         }
  111.         // 顧客とLINEユーザーIDをひも付け(line_login_integrationテーブルのレコードを作成)
  112.         log_info('LINEユーザーとの関連付け開始');
  113.         $lineUserId $this->session->get(LineLoginIntegrationController::PLUGIN_LINE_LOGIN_INTEGRATION_SSO_USERID);
  114.         if (!empty($lineUserId)) {
  115.             log_info('LINEログインしているため、ユーザーとの関連付けを実行');
  116.             $this->lineLoginIntegration $this->lineLoginIntegrationRepository->findOneBy(['line_user_id' => $lineUserId]);
  117.             if (empty($this->lineLoginIntegration)) {
  118.                 $customer $event['Customer'];
  119.                 log_info('LINE IDとユーザーの関連付けを開始', [$customer['id']]);
  120.                 $lineLoginIntegration = new LineLoginIntegration();
  121.                 $lineLoginIntegration->setLineUserId($lineUserId);
  122.                 $lineLoginIntegration->setCustomer($customer);
  123.                 $lineLoginIntegration->setCustomerId($customer['id']);
  124.                 $this->entityManager->persist($lineLoginIntegration);
  125.                 $this->entityManager->flush($lineLoginIntegration);
  126.                 log_info('LINEユーザーとの関連付け終了');
  127.             }
  128.             log_info('LINEユーザーとの関連付け終了');
  129.         } else {
  130.             log_info('LINE未ログインのため関連付け未実施');
  131.         }
  132.     }
  133.     /**
  134.      * ログイン画面にLINEボタンを出力します
  135.      * @param TemplateEvent $event
  136.      */
  137.     public function onRenderLineLoginButton(TemplateEvent $event)
  138.     {
  139.         if (!$this->isLineSettingCompleted()) {
  140.             return;
  141.         }
  142.         $linkUrl $this->router->generate("plugin_line_login", array(), UrlGeneratorInterface::ABSOLUTE_URL);
  143.         $imgUrl $this->router->generate("homepage", array(),
  144.                 UrlGeneratorInterface::ABSOLUTE_URL) . 'html/plugin/line_login_integration/assets/img/btn_login_base.png';
  145.         $snipet  '<div class="plugin_line_login btn" style=""><a href="' $linkUrl '" class="line-button"><img src="' $imgUrl '" alt="LINEログイン"></a></div><br>' PHP_EOL;
  146.         $snipet .= '<div class="plugin_line_login col" style="margin-top:-10px; padding:10px;">ログイン後にマイページからも「LINEでログイン」の設定がおこなえます。</div>';
  147.         $search '<div class="ec-off2Grid__cell">';
  148.         $replace $search $snipet;
  149.         $source str_replace($search$replace$event->getSource());
  150.         $event->setSource($source);
  151.     }
  152.     /**
  153.      * カート経由のログイン画面にLINEボタンを出力します
  154.      * @param TemplateEvent $event
  155.      */
  156.     public function onRenderShoppingLineLoginButton(TemplateEvent $event)
  157.     {
  158.         if (!$this->isLineSettingCompleted()) {
  159.             return;
  160.         }
  161.         $linkUrl $this->router->generate("plugin_line_login", array(), UrlGeneratorInterface::ABSOLUTE_URL);
  162.         $imgUrl $this->router->generate("homepage", array(),
  163.                 UrlGeneratorInterface::ABSOLUTE_URL) . 'html/plugin/line_login_integration/assets/img/btn_login_base.png';
  164.         $snipet '<div class="btn" style=""><a href="' $linkUrl '" class="line-button"><img src="' $imgUrl '" alt="LINEログイン"></a></div><br>' PHP_EOL;
  165.         $search '<div class="ec-grid3__cell2">';
  166.         $replace $search $snipet;
  167.         $source str_replace($search$replace$event->getSource());
  168.         $event->setSource($source);
  169.     }
  170.     /**
  171.      * 会員情報変更画面の表示
  172.      * @param TemplateEvent $event
  173.      */
  174.     public function onRenderMypageChange(TemplateEvent $event)
  175.     {
  176.         if (!$this->isLineSettingCompleted()) {
  177.             return;
  178.         }
  179.         $form $event->getParameter('form');
  180.         $customerId $form->vars['value']['id'];
  181.         if (empty($customerId)) {
  182.             error_log("会員IDを取得できませんでした", [$form]);
  183.             return;
  184.         }
  185.         $lineIdBySession $this->session
  186.             ->get(LineLoginIntegrationController::PLUGIN_LINE_LOGIN_INTEGRATION_SSO_USERID);
  187.         if (empty($lineIdBySession)) {
  188.             $lineLoginIntegration $this->lineLoginIntegrationRepository
  189.                 ->findOneBy(['customer_id' => $customerId]);
  190.         } else{
  191.             $lineLoginIntegration $this->lineLoginIntegrationRepository
  192.                 ->findOneBy(['customer_id' => $customerId'line_user_id' => $lineIdBySession]);
  193.         }
  194.         // LINEとの紐づけがないとき
  195.         if (empty($lineLoginIntegration)) {
  196.             // LINEのログインボタン表示
  197.             $linkUrl $this->router->generate("plugin_line_login", array(), UrlGeneratorInterface::ABSOLUTE_URL);
  198.             $imgUrl $this->router->generate("homepage", array(),
  199.                     UrlGeneratorInterface::ABSOLUTE_URL) . 'html/plugin/line_login_integration/assets/img/btn_register_base.png';
  200.             $snipet '<div class="btn"><a href="' $linkUrl '" class="line-button"><img src="' $imgUrl '" alt="LINEで登録"></a></div>' PHP_EOL;
  201.             $snipet .= PHP_EOL;
  202.             $snipet .= '<div class="col" style="padding-bottom:10px;">「LINEで登録」ボタンを押してLINEにログインすると、LINEアカウントでログインできるようになります。</div>';
  203.             $snipet .= PHP_EOL;
  204.         }
  205.         // LINEとの紐づけがあっても、現在LINEにログインしていないっぽいとき
  206.         else if (empty($lineIdBySession)) {
  207.             // LINEのログインボタン表示
  208.             $linkUrl $this->router->generate("plugin_line_login", array(), UrlGeneratorInterface::ABSOLUTE_URL);
  209.             $imgUrl $this->router->generate("homepage", array(),
  210.                     UrlGeneratorInterface::ABSOLUTE_URL) . 'html/plugin/line_login_integration/assets/img/btn_login_base.png';
  211.             $snipet '<div class="btn"><a href="' $linkUrl '" class="line-button"><img src="' $imgUrl '" alt="LINEで登録"></a></div>' PHP_EOL;
  212.             $snipet .= PHP_EOL;
  213. /*
  214.             $snipet .= '<div class="col" style="padding-bottom:10px;">LINEアカウントと連携済みですが、現在LINEでログインしていません。</div>';
  215.             $snipet .= PHP_EOL;
  216. */
  217.         }
  218.         // LINEとの紐づけがあって、かつLINEにログイン中のとき
  219.         else {
  220.             //自分のLINEIDとの連携ではなかった場合は連携ボタンを表示する
  221.             if ($lineIdBySession != $lineLoginIntegration['line_user_id'] || !$lineLoginIntegration['contact_email']) {
  222.                 // LINEのログインボタン表示
  223.                 $linkUrl $this->router->generate("plugin_line_login", array(), UrlGeneratorInterface::ABSOLUTE_URL);
  224.                 $imgUrl $this->router->generate("homepage", array(),
  225.                         UrlGeneratorInterface::ABSOLUTE_URL) . 'html/plugin/line_login_integration/assets/img/btn_register_base.png';
  226.                 $snipet '<div class="btn"><a href="' $linkUrl '" class="line-button"><img src="' $imgUrl '" alt="LINEで登録"></a></div>' PHP_EOL;
  227.                 $snipet .= PHP_EOL;
  228.                 $snipet .= '<div class="col" style="padding-bottom:10px;">「LINEで登録」ボタンを押してLINEにログインすると、LINEアカウントでログインできるようになります。</div>';
  229.                 $snipet .= PHP_EOL;
  230.             } else {
  231.                 // 連携解除項目を追加
  232.                 $this->replaceMypageChangeForm($event);
  233.                 $snipet '<div class="col" style="padding-bottom:10px;">LINEアカウント連携済です。解除したいときは「LINE連携 解除」をチェックして「登録する」ボタンを押してください。<br>アカウントに紐づくすべてのLINE連携が解除されます。</div>';
  234.                 $snipet .= PHP_EOL;
  235.             }
  236.         }
  237.         $search '<div class="ec-off1Grid__cell">';
  238.         $replace $search $snipet;
  239.         $source str_replace($search$replace$event->getSource());
  240.         $event->setSource($source);
  241.     }
  242.     /**
  243.      * 会員情報編集完了時のイベント処理を行います
  244.      *
  245.      * @param EventArgs $event
  246.      */
  247.     public function onCompleteMypageChange(EventArgs $event)
  248.     {
  249.         if (!$this->isLineSettingCompleted()) {
  250.             return;
  251.         }
  252.         $customerId $event['Customer']->getId();
  253.         $lineLoginIntegration $this->lineLoginIntegrationRepository->findOneBy(['customer_id' => $customerId]);
  254.         // LINEの紐づけがすでにあるとき
  255.         if (!empty($lineLoginIntegration)) {
  256.             $form $event['form'];
  257.             // LINE情報を削除する
  258.             $is_line_delete 0;
  259.             if ($form->has('is_line_delete')) {
  260.                 $is_line_delete $form->get('is_line_delete')->getData();
  261.             }
  262.             if ($is_line_delete == 1) {
  263.                 $lineUserId $this->session->get(LineLoginIntegrationController::PLUGIN_LINE_LOGIN_INTEGRATION_SSO_USERID);
  264.                 // 連携解除
  265.                 $this->lineIdUnassociate($customerId$lineUserIdtrue);
  266.             }
  267.         }
  268.         // LINEの紐づけがないとき
  269.         else {
  270.             // 何もしない
  271.             // LINEとの紐づけ処理はログインのコールバック関数(LineLoginIntegrationController.php)内で行われるのでここでは行わない
  272.         }
  273.     }
  274.     /**
  275.      * 会員がマイページから退会手続きを行ったとき
  276.      *
  277.      * 退会した会員のLINE連携を解除する
  278.      *
  279.      * @param EventArgs $event
  280.      */
  281.     public function onCompleteMypageWithdraw(EventArgs $event)
  282.     {
  283.         if (!$this->isLineSettingCompleted()) {
  284.             return;
  285.         }
  286.         log_info('マイページから退会');
  287.         $customerId $event['Customer']['id'];
  288.         $lineUserId $this->session->get(LineLoginIntegrationController::PLUGIN_LINE_LOGIN_INTEGRATION_SSO_USERID);
  289.         $this->lineIdUnassociate($customerId$lineUserIdtrue);
  290.     }
  291.     /**
  292.      * 管理画面から顧客情報を更新したとき
  293.      *
  294.      * 会員を退会にした場合にはLINE連携を解除する
  295.      *
  296.      * @param EventArgs $event
  297.      */
  298.     public function onCompleteCustomerEdit(EventArgs $event)
  299.     {
  300.         if (!$this->isLineSettingCompleted()) {
  301.             return;
  302.         }
  303.         $customerId $event['Customer']->getId();
  304.         $customerStatus $event['Customer']->getStatus();
  305.         // 退会扱いのとき
  306.         if ($customerStatus['id'] == CustomerStatus::WITHDRAWING) {
  307.             log_info('仮画面の会員情報編集ページから退会扱い');
  308.             $this->lineIdUnassociate($customerId);
  309.         }
  310.     }
  311.     /**
  312.      * LINE設定が初期化済みかチェックする
  313.      */
  314.     private function isLineSettingCompleted()
  315.     {
  316.         $lineLoginIntegrationSetting $this->lineLoginIntegrationSettingRepository
  317.             ->find(LineLoginIntegrationAdminController::LINE_LOGIN_INTEGRATION_SETTING_TABLE_ID);
  318.         if (empty($lineLoginIntegrationSetting)) {
  319.             log_error("Line Lineの情報が未設定です");
  320.             return false;
  321.         }
  322.         $lineChannelId $lineLoginIntegrationSetting->getLineChannelId();
  323.         if (empty($lineChannelId)) {
  324.             log_error("Line Channel Idが未設定です");
  325.             return false;
  326.         }
  327.         $lineChannelSecret $lineLoginIntegrationSetting->getLineChannelSecret();
  328.         if (empty($lineChannelSecret)) {
  329.             log_error("Line Channel Secretが未設定です");
  330.             return false;
  331.         }
  332.         return true;
  333.     }
  334.     /**
  335.      * LINEアカウントとの連携を解除する処理
  336.      *
  337.      * 会員IDから連携DBを検索し、該当するレコードを削除する処理。管理画面でなくフロントからのフローでは、
  338.      * セッションを削除するのでフラグをtrueにしておく
  339.      *
  340.      * @param int $customerId       LINEとの連携を解除したい会員ID
  341.      * @param int $lineUserId       LINEUserID
  342.      * @param bool $isDeleteSession セッションまで削除する。デフォでfalse
  343.      * @return bool                 会員がLINEと紐づけされていて、紐づけを解除したときにtrueを返す
  344.      */
  345.     private function lineIdUnassociate(int $customerIdint $lineUserId null, ?bool $isDeleteSession null)
  346.     {
  347.         if ($lineUserId) {
  348.             $lineLoginIntegration $this->lineLoginIntegrationRepository->findOneBy(['customer_id' => $customerId'line_user_id' => $lineUserId]);
  349.             // LINE情報を削除する
  350.             if (!empty($lineLoginIntegration)) {
  351.                 log_info('customer_id:' $customerId 'のLINE連携を解除');
  352.                 $this->lineLoginIntegrationRepository->deleteLineAssociation($lineLoginIntegration);
  353.                 log_info('LINEの連携を解除しました');
  354.     
  355.                 if ($isDeleteSession) {
  356.                     $this->session->remove(LineLoginIntegrationController::PLUGIN_LINE_LOGIN_INTEGRATION_SSO_STATE);
  357.                     $this->session->remove(LineLoginIntegrationController::PLUGIN_LINE_LOGIN_INTEGRATION_SSO_USERID);
  358.                     if(isset($this->session->is_line_delete)) {
  359.                         $this->session->remove($this->session->is_line_delete);
  360.                     }
  361.                 }
  362.                 return true;
  363.             }
  364.         }else{
  365.             $lineLoginIntegrations $this->lineLoginIntegrationRepository->findBy(['customer_id' => $customerId]);
  366.             // LINE情報を削除する
  367.             if (!empty($lineLoginIntegrations)) {
  368.                 log_info('customer_id:' $customerId 'のLINE連携を解除');
  369.                 foreach ($lineLoginIntegrations as $lineLoginIntegration) {
  370.                     $this->lineLoginIntegrationRepository->deleteLineAssociation($lineLoginIntegration);
  371.                 }
  372.                 log_info('LINEの連携を解除しました');
  373.     
  374.                 if ($isDeleteSession) {
  375.                     $this->session->remove(LineLoginIntegrationController::PLUGIN_LINE_LOGIN_INTEGRATION_SSO_STATE);
  376.                     $this->session->remove(LineLoginIntegrationController::PLUGIN_LINE_LOGIN_INTEGRATION_SSO_USERID);
  377.                     if(isset($this->session->is_line_delete)) {
  378.                         $this->session->remove($this->session->is_line_delete);
  379.                     }
  380.                 }
  381.                 return true;
  382.             }
  383.         }
  384.         return false;
  385.     }
  386.     private function replaceMypageChangeForm(TemplateEvent $event)
  387.     {
  388.         log_info('LINE連携削除を追加');
  389.         $snipet $this->twig->getLoader()->getSourceContext('ECCUBE4LineLoginIntegration42/Resource/template/mypage_change_add_is_line_delete.twig')->getCode();
  390.         $search '{# エンティティ拡張の自動出力 #}';
  391.         $replace $search $snipet;
  392.         $source str_replace($search$replace$event->getSource());
  393.         $event->setSource($source);
  394.     }
  395. }