app/Plugin/ECCUBE4LineLoginIntegration42/LineLoginIntegrationEvent.php line 42

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