app/Plugin/ECCUBE4LineIntegration42/LineIntegrationEvent.php line 280

Open in your IDE?
  1. <?php
  2. namespace Plugin\ECCUBE4LineIntegration42;
  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\ECCUBE4LineIntegration42\Repository\LineIntegrationRepository;
  11. use Plugin\ECCUBE4LineIntegration42\Repository\LineIntegrationSettingRepository;
  12. use Plugin\ECCUBE4LineIntegration42\Controller\Admin\LineIntegrationAdminController;
  13. use Plugin\ECCUBE4LineIntegration42\Controller\LineIntegrationController;
  14. use Plugin\ECCUBE4LineIntegration42\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.             EccubeEvents::FRONT_MYPAGE_CHANGE_INDEX_COMPLETE => 'onCompleteMypageChange',
  54.             EccubeEvents::FRONT_MYPAGE_WITHDRAW_INDEX_COMPLETE => 'onCompleteMypageWithdraw',
  55.             EccubeEvents::ADMIN_CUSTOMER_EDIT_INDEX_COMPLETE => 'onCompleteCustomerEdit',
  56.         ];
  57.     }
  58.     /**
  59.      * 新規会員登録画面の表示
  60.      *
  61.      * @param TemplateEvent $event
  62.      * @throws \Twig_Error_Loader
  63.      */
  64.     public function onRenderEntryIndex(TemplateEvent $event)
  65.     {
  66.         if (!$this->isLineSettingCompleted()) {
  67.             return;
  68.         }
  69.         $lineUserId $this->session
  70.             ->get(LineIntegrationController::PLUGIN_LINE_INTEGRATION_SSO_USERID);
  71.         if (!empty($lineUserId)) {
  72.             // LINE通知のチェックボックスを表示
  73.             // →現状では表示しても無視されてしまうので表示しないように
  74. //            $this->replaceTwig($event, 'entry_add_line_notification.twig');
  75.         }
  76.     }
  77.     /**
  78.      * 新規会員登録画面へLINEボタンを出力
  79.      *
  80.      * @param TemplateEvent $event
  81.      */
  82.     public function onRenderLineEntryButton(TemplateEvent $event)
  83.     {
  84.         if (!$this->isLineSettingCompleted()) {
  85.             return;
  86.         }
  87.         $lineUserId $this->session
  88.             ->get(LineIntegrationController::PLUGIN_LINE_INTEGRATION_SSO_USERID);
  89.         $linkUrl $this->router->generate("plugin_line_login", array(),
  90.             UrlGeneratorInterface::ABSOLUTE_URL);
  91.         $imgUrl $this->router->generate("homepage", array(),
  92.                 UrlGeneratorInterface::ABSOLUTE_URL)
  93.             . 'html/plugin/line_integration/assets/img/btn_register_base.png';
  94.         $snipet '';
  95.         // LINEボタンを表示
  96.         if (empty($lineUserId)) {
  97.             $snipet .= '<div class="btn" style=""><a href="' $linkUrl '" class="line-button"><img src="' $imgUrl '" alt="LINEで登録"></a></div>' PHP_EOL;
  98.             $snipet .= PHP_EOL;
  99.         }
  100.         // LINEにログイン済みなので登録を促す
  101.         else {
  102.             $snipet .= '<div class="col" style="margin-top:-10px; padding:10px;">LINEログイン済みです。この会員登録が完了すると、LINEでログインできるようになります。</div>';
  103.             $snipet .= PHP_EOL;
  104.         }
  105.         $search '<div class="ec-off1Grid__cell">';
  106.         $replace $search $snipet;
  107.         $source str_replace($search$replace$event->getSource());
  108.         $event->setSource($source);
  109.     }
  110.     /**
  111.      * 会員登録処理完了時のLINE連携解除処理
  112.      *
  113.      * @param EventArgs $event
  114.      */
  115.     public function onCompleteEntry(EventArgs $event)
  116.     {
  117.         if (!$this->isLineSettingCompleted()) {
  118.             return;
  119.         }
  120.         $lineUserId $this->session
  121.             ->get(LineIntegrationController::PLUGIN_LINE_INTEGRATION_SSO_USERID);
  122.         if (!empty($lineUserId)) {
  123.             // 顧客とLINEユーザーIDをひも付け(line_integrationテーブルのレコードを作成)
  124.             log_info('LINEログインしているため、ユーザーとの関連付けを実行');
  125.             $this->lineIntegration $this->lineIntegrationRepository
  126.                 ->findOneBy(['line_user_id' => $lineUserId]);
  127.             $line_notificationFlg $event['form']->get('line_notification_flg')->getData();
  128.             if (empty($this->lineIntegration)) {
  129.                 $customer $event['Customer'];
  130.                 log_info('LINE IDとユーザーの関連付けを開始', [$customer['id']]);
  131.                 $lineIntegration = new LineIntegration();
  132.                 $lineIntegration->setLineUserId($lineUserId);
  133.                 $lineIntegration->setLineNotificationFlg($line_notificationFlg);
  134.                 $lineIntegration->setDelFlg(0);
  135.                 $lineIntegration->setCustomer($customer);
  136.                 $lineIntegration->setCustomerId($customer['id']);
  137.                 $this->entityManager->persist($lineIntegration);
  138.                 $this->entityManager->flush($lineIntegration);
  139.                 log_info('LINEユーザーとの関連付け終了');
  140.             } else {
  141.                 log_error('新規登録フローで、既に関連付けされているLINE IDを検知。');
  142.             }
  143.         } else {
  144.             log_info('LINE未ログインのため関連付け未実施');
  145.         }
  146.     }
  147.     /**
  148.      * ログイン画面へLINEボタンを出力
  149.      *
  150.      * @param TemplateEvent $event
  151.      */
  152.     public function onRenderLineLoginButton(TemplateEvent $event)
  153.     {
  154.         if (!$this->isLineSettingCompleted()) {
  155.             return;
  156.         }
  157.         $linkUrl $this->router->generate("plugin_line_login",array(),
  158.             UrlGeneratorInterface::ABSOLUTE_URL);
  159.         $imgUrl $this->router->generate("homepage",array(),
  160.                 UrlGeneratorInterface::ABSOLUTE_URL)
  161.             .'html/plugin/line_integration/assets/img/btn_login_base.png';
  162.         $snipet '<div class="lineLogin__btn" style=""><a href="' $linkUrl '" class="line-button"><img src="' $imgUrl '" alt="LINEログイン"></a></div>' PHP_EOL;
  163.         // $search = '<div class="ec-off2Grid__cell">';
  164.         $search '<div class="lineLogin">';
  165.         $replace $search $snipet;
  166.         $source str_replace($search$replace$event->getSource());
  167.         $event->setSource($source);
  168.     }
  169.     /**
  170.      * カート経由のログイン画面にLINEボタンを出力します
  171.      * @param TemplateEvent $event
  172.      */
  173.     public function onRenderShoppingLineLoginButton(TemplateEvent $event)
  174.     {
  175.         if (!$this->isLineSettingCompleted()) {
  176.             return;
  177.         }
  178.         $linkUrl $this->router->generate("plugin_line_login", array(), UrlGeneratorInterface::ABSOLUTE_URL);
  179.         $imgUrl $this->router->generate("homepage", array(),
  180.                 UrlGeneratorInterface::ABSOLUTE_URL) . 'html/plugin/line_integration/assets/img/btn_login_base.png';
  181.         $snipet '<div class="btn" style=""><a href="' $linkUrl '" class="line-button"><img src="' $imgUrl '" alt="LINEログイン"></a></div><br>' PHP_EOL;
  182.         $search '<div class="ec-grid3__cell3">';
  183.         $replace $search $snipet;
  184.         $source str_replace($search$replace$event->getSource());
  185.         $event->setSource($source);
  186.     }
  187.     /**
  188.      * 会員情報変更画面の表示
  189.      *
  190.      * @param TemplateEvent $event
  191.      * @throws \Twig_Error_Loader
  192.      */
  193.     public function onRenderMypageChange(TemplateEvent $event)
  194.     {
  195.         if (!$this->isLineSettingCompleted()) {
  196.             return;
  197.         }
  198.         $form $event->getParameter('form');
  199.         $customerId $form->vars['value']['id'];
  200.         if (empty($customerId)) {
  201.             error_log("会員IDを取得できませんでした", [$form]);
  202.             return;
  203.         }
  204.         $lineIntegration $this->lineIntegrationRepository
  205.             ->findOneBy(['customer_id' => $customerId]);
  206.         $lineIdBySession $this->session
  207.             ->get(LineIntegrationController::PLUGIN_LINE_INTEGRATION_SSO_USERID);
  208.         // LINEとの紐づけがないとき
  209.         if (empty($lineIntegration)) {
  210.             // LINEのログインボタン表示
  211.             $linkUrl $this->router->generate("plugin_line_login", array(),
  212.                 UrlGeneratorInterface::ABSOLUTE_URL);
  213.             $imgUrl $this->router->generate("homepage", array(),
  214.                     UrlGeneratorInterface::ABSOLUTE_URL) . 'html/plugin/line_integration/assets/img/btn_register_base.png';
  215.             $snipet '<div class="lineMypage__btn"><a href="' $linkUrl '" class="line-button"><img src="' $imgUrl '" alt="LINEで登録"></a></div>' PHP_EOL;
  216.             $snipet .= PHP_EOL;
  217.             $snipet .= '<div class="lineMypage__notice">※「LINEで登録」ボタンを押してLINEにログインすると、LINEアカウントでログインできるようになります。</div>';
  218.             $snipet .= PHP_EOL;
  219.         }
  220.         // LINEとの紐づけがあっても、現在LINEにログインしていないっぽいとき
  221.         else if (empty($lineIdBySession)) {
  222.             // LINEのログインボタン表示
  223.             $linkUrl $this->router->generate("plugin_line_login", array(),
  224.                 UrlGeneratorInterface::ABSOLUTE_URL);
  225.             $imgUrl $this->router->generate("homepage", array(),
  226.                     UrlGeneratorInterface::ABSOLUTE_URL) . 'html/plugin/line_integration/assets/img/btn_login_base.png';
  227.             $snipet '<div class="lineMypage__btn"><a href="' $linkUrl '" class="line-button"><img src="' $imgUrl '" alt="LINEでログイン"></a></div>' PHP_EOL;
  228.             $snipet .= PHP_EOL;
  229.             $snipet .= '<div class="lineMypage__notice">LINEアカウントと連携済みですが、現在LINEでログインしていません。</div>';
  230.             $snipet .= PHP_EOL;
  231.         }
  232.         // LINEとの紐づけがあって、かつLINEにログイン中のとき
  233.         else {
  234.             // 連携解除項目を追加
  235.             $this->replaceTwig($event,'mypage_change_add_is_line_delete.twig');
  236.             // 上部にLINE連携済みである旨を通知
  237.             $snipet '<div class="lineMypage__notice">※LINEアカウント連携済です。<br class="sp-show">解除したいときは「LINE連携 解除」をチェックして「登録する」ボタンを押してください。</div>';
  238.             $snipet .= PHP_EOL;
  239.         }
  240.         // $search = '<div class="ec-off1Grid__cell">';
  241.         $search '<div class="lineMypage">';
  242.         
  243.         $replace $search $snipet;
  244.         $source str_replace($search$replace$event->getSource());
  245.         $event->setSource($source);
  246.         // LINE通知のチェックボックスを表示
  247. //        $this->replaceTwig($event, 'entry_add_line_notification.twig');
  248.     }
  249.     /**
  250.      * 会員情報編集完了時の処理
  251.      *
  252.      * @param EventArgs $event
  253.      */
  254.     public function onCompleteMypageChange(EventArgs $event)
  255.     {
  256.         if (!$this->isLineSettingCompleted()) {
  257.             return;
  258.         }
  259.         $customerId $event['Customer']->getId();
  260.         $lineIntegration $this->lineIntegrationRepository
  261.             ->findOneBy(['customer_id' => $customerId]);
  262.         // LINEの紐づけがすでにあるとき
  263.         if (!empty($lineIntegration)) {
  264.             $form $event['form'];
  265.             if ($form->has('line_notification_flg')) {
  266.                 $line_notification_flg $form->get('line_notification_flg')->getData();
  267.                 $lineIntegration->setLineNotificationFlg($line_notification_flg);
  268.                 $this->entityManager->persist($lineIntegration);
  269.                 $this->entityManager->flush();
  270.             }
  271.             // LINE情報を削除する
  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('ECCUBE4LineIntegration42/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. }