app/Plugin/ECCUBE4LineIntegration/LineIntegrationEvent.php line 441

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