app/Plugin/ECCUBE4LineLoginIntegration/LineLoginIntegrationEvent.php line 153

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