eccube4 ログイン履歴（会員）の作成

<p>eccubeで開発を行っていると管理画面からのログイン履歴はデフォルトで用意されているが、会員がログインした際にもログイン履歴を残していきたいということもあると思いました。

そこで今回は会員のログイン履歴テーブルを新規追加して、ログインが成功した場合にイベントリスナーを実行してログイン者データを保存する部分を記載していきます。
</p>

<h2>新規テーブルの作成</h2>

<p>下記のファイルを作成<br>
root/app/Customize/Entity/SampleLoginHistory.php
</P>

```ph
<?php

namespace Customize\Entity;

use Doctrine\ORM\Mapping as ORM;
use Eccube\Entity\AbstractEntity;

if (!class_exists('\Customize\Entity\SampleLoginHistory')) {
    /**
     * SampleLoginHistory
     *
     * @ORM\Table(name="dtb_sample_login_history")
     * @ORM\InheritanceType("SINGLE_TABLE")
     * @ORM\DiscriminatorColumn(name="discriminator_type", type="string", length=255)
     * @ORM\HasLifecycleCallbacks()
     * @ORM\Entity(repositoryClass="Customize\Repository\SampleLoginHistoryRepository")
     */
    class SampleLoginHistory extends AbstractEntity
    {
        /**
         * @var int
         *
         * @ORM\Column(name="id", type="integer", options={"unsigned":true})
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="IDENTITY")
         */
        private $id;

        /**
         * @var string
         * @ORM\Column(type="text",nullable=true)
         */
        private $login_user_name;

        /**
         * @var \DateTime
         *
         * @ORM\Column(name="create_date", type="datetimetz")
         */
        private $create_date;

        /**
         * @var \DateTime
         *
         * @ORM\Column(name="update_date", type="datetimetz")
         */
        private $update_date;

        /**
         * @var Customer
         * @ORM\ManyToOne(targetEntity="Eccube\Entity\Customer")
         * @ORM\JoinColumns({
         *   @ORM\JoinColumn(name="customer_id", referencedColumnName="id", onDelete="SET NULL")
         * })
         */
        private $CustomerLoginUser;


        /**
         * Get id
         *
         * @return integer
         */
        public function getId()
        {
            return $this->id;
        }

        /**
         * Set login_user_name
         *
         * @param string $login_user_name
         *
         * @return CustomerLoginHistory
         */
        public function setLoginUserName($LoginUserName)
        {
            $this->login_user_name = $LoginUserName;

            return $this;
        }

        /**
         * Get login_user_name
         *
         * @return string
         */
        public function getLoginUserName()
        {
            return $this->login_user_name;
        }

        /**
         * Set create_date
         *
         * @param \DateTime $createDate
         *
         * @return CustomerLoginHistory
         */
        public function setCreateDate($createDate)
        {
            $this->create_date = $createDate;

            return $this;
        }

        /**
         * Get create_date
         *
         * @return \DateTime
         */
        public function getCreateDate()
        {
            return $this->create_date;
        }

        /**
         * Set update_date
         *
         * @param \DateTime $updateDate
         *
         * @return CustomerLoginHistory
         */
        public function setUpdateDate($updateDate)
        {
            $this->update_date = $updateDate;

            return $this;
        }

        /**
         * Get update_date
         *
         * @return \DateTime
         */
        public function getUpdateDate()
        {
            return $this->update_date;
        }

        /**
         * Set CustomerLoginUser
         *
         * @param \Eccube\Entity\Customer $CustomerLoginUser
         *
         * @return CustomerLoginHistory
         */
        public function setCustomerLoginUser(\Eccube\Entity\Customer $customerLoginUser = null)
        {
            $this->CustomerLoginUser = $customerLoginUser;

            return $this;
        }

        /**
         * Get CustomerLoginUser
         *
         * @return Customer
         */
        public function getCustomerLoginUser()
        {
            return $this->CustomerLoginUser;
        }
    }
}
```

<p>repositryの作成<br>
root/app/Customize/Repository/SampleLoginHistoryRepository.php</p>

```php
<?php

namespace Customize\Repository;

use Customize\Entity\CustomerLoginHistory;
use Eccube\Repository\AbstractRepository;
use Doctrine\Persistence\ManagerRegistry as RegistryInterface;

/**
 * SampleLoginHistoryRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class SampleLoginHistoryRepository extends AbstractRepository
{
    /**
     * SampleLoginHistoryRepository constructor.
     *
     * @param RegistryInterface $registry
     * @param Queries $queries
     * @param EccubeConfig $eccubeConfig
     */
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, CustomerLoginHistory::class);
    }
}
```

<p>上記作成ができたらターミナルからコマンドでテーブルを新規追加していきます。</p>

```sql
// キャッシュクリア
php [EC-CUBEｲﾝｽﾄｰﾙﾃﾞｨﾚｸﾄﾘ]/bin/console cache:clear --no-warmup

// テーブル追加SQL実行('--force'を付けずに叩くと、実行予定のSQL文が表示されます)
php [EC-CUBEｲﾝｽﾄｰﾙﾃﾞｨﾚｸﾄﾘ]/bin/console eccube:schema:update --dump-sql --force
```

<h2>ログイン直後イベントリスナー</h2>

<p>下記ファイルを作成<br>
root/app/Customize/EventListener/SampleLoginHistoryListener.php</p>

```php
<?php

namespace Customize\EventListener;

use Doctrine\ORM\EntityManagerInterface;
use Customize\Entity\SampleLoginHistory;
use Eccube\Entity\Customer;
use Eccube\Request\Context;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\Event\LoginFailureEvent;
use Symfony\Component\Security\Http\SecurityEvents;

class SampleLoginHistoryListener implements EventSubscriberInterface
{
    /**
     * @var EntityManagerInterface
     */
    private $entityManager;

    /**
     * @var RequestStack
     */
    private $requestStack;

    /**
     * @var Context
     */
    private $requestContext;


    public function __construct(
        EntityManagerInterface $em,
        RequestStack $requestStack,
        Context $requestContext
    ) {
        $this->entityManager = $em;
        $this->requestStack = $requestStack;
        $this->requestContext = $requestContext;
    }

    public static function getSubscribedEvents()
    {
        return [
            // 登録するイベントとそれに対応するメソッドを指定する
            SecurityEvents::INTERACTIVE_LOGIN => 'onCustomerLogin',
        ];
    }

    public function onCustomerLogin(InteractiveLoginEvent $event)
    {
        // ユーザーログイン時の処理を記述する
        $request = $event->getRequest();
        $user = $event
            ->getAuthenticationToken()
            ->getUser();

        if ($user instanceof Customer) {
                $SampleLoginHistory = new SampleLoginHistory();
                $SampleLoginHistory
                    ->setCustomerLoginUser($user)
                    ->setLoginUserName($user->getUsername());
                $this->entityManager->persist($SampleLoginHistory);
                $this->entityManager->flush();
        }
    }
}
```