<?php
namespace Plugin\NZGoogleLogin42\Event;
use Eccube\Entity\Customer;
use Eccube\Event\EccubeEvents;
use Eccube\Event\EventArgs;
use Plugin\NZGoogleLogin42\Entity\CustomerOAuth;
use Plugin\NZGoogleLogin42\Repository\CustomerOAuthRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class EntryEventSubscriber implements EventSubscriberInterface
{
/**
* @var RequestStack
*/
private $requestStack;
/**
* @var EntityManagerInterface
*/
private $entityManager;
/**
* @var CustomerOAuthRepository
*/
private $customerOAuthRepository;
// セッションキー定数(GoogleLoginControllerと同じ)
private const SESSION_GOOGLE_DATA = 'nz_google_login_data';
// Googleデータの有効期限(30分)
private const GOOGLE_DATA_EXPIRY = 1800;
public function __construct(
RequestStack $requestStack,
EntityManagerInterface $entityManager,
CustomerOAuthRepository $customerOAuthRepository
) {
$this->requestStack = $requestStack;
$this->entityManager = $entityManager;
$this->customerOAuthRepository = $customerOAuthRepository;
}
public static function getSubscribedEvents()
{
return [
EccubeEvents::FRONT_ENTRY_INDEX_COMPLETE => 'onEntryComplete',
];
}
/**
* 会員登録完了時にGoogle連携を保存
*/
public function onEntryComplete(EventArgs $event)
{
try {
$request = $this->requestStack->getCurrentRequest();
if (!$request || !$request->hasSession()) {
return;
}
$session = $request->getSession();
$googleData = $session->get(self::SESSION_GOOGLE_DATA);
if (!$googleData) {
return;
}
// データの有効性チェック
if (!isset($googleData['google_id']) || !isset($googleData['email'])) {
log_warning('[NZGoogleLogin] Invalid Google data in session', [
'keys' => array_keys($googleData),
]);
$session->remove(self::SESSION_GOOGLE_DATA);
return;
}
// タイムスタンプチェック(30分以上経過していたら無効)
if (isset($googleData['timestamp'])) {
$elapsed = time() - $googleData['timestamp'];
if ($elapsed > self::GOOGLE_DATA_EXPIRY) {
log_warning('[NZGoogleLogin] Google data expired', [
'elapsed_seconds' => $elapsed,
]);
$session->remove(self::SESSION_GOOGLE_DATA);
return;
}
}
/** @var Customer $Customer */
$Customer = $event->getArgument('Customer');
if (!$Customer || !$Customer->getId()) {
log_error('[NZGoogleLogin] Customer not found in entry complete event');
$session->remove(self::SESSION_GOOGLE_DATA);
return;
}
// 既に同じGoogle IDで連携がないかチェック
$existingOAuth = $this->customerOAuthRepository->findByGoogleId($googleData['google_id']);
if ($existingOAuth) {
log_warning('[NZGoogleLogin] Google ID already linked to another customer', [
'google_id' => substr($googleData['google_id'], 0, 10) . '...',
'existing_customer_id' => $existingOAuth->getCustomer()->getId(),
'new_customer_id' => $Customer->getId(),
]);
$session->remove(self::SESSION_GOOGLE_DATA);
return;
}
// この顧客に既にOAuth連携がないかチェック
$customerOAuth = $this->customerOAuthRepository->findByCustomerId($Customer->getId());
if ($customerOAuth) {
// 既存の連携を更新
$customerOAuth->setGoogleId($googleData['google_id']);
$customerOAuth->setEmail($googleData['email']);
$customerOAuth->setUpdateDate(new \DateTime());
log_info('[NZGoogleLogin] Updated existing OAuth link', [
'customer_id' => $Customer->getId(),
]);
} else {
// Google連携情報を新規保存
$CustomerOAuth = new CustomerOAuth();
$CustomerOAuth->setCustomer($Customer);
$CustomerOAuth->setGoogleId($googleData['google_id']);
$CustomerOAuth->setEmail($googleData['email']);
$CustomerOAuth->setCreateDate(new \DateTime());
$CustomerOAuth->setUpdateDate(new \DateTime());
$this->entityManager->persist($CustomerOAuth);
log_info('[NZGoogleLogin] Created new OAuth link', [
'customer_id' => $Customer->getId(),
'google_id' => substr($googleData['google_id'], 0, 10) . '...',
]);
}
$this->entityManager->flush();
// セッションからGoogle情報を削除
$session->remove(self::SESSION_GOOGLE_DATA);
} catch (\Exception $e) {
log_error('[NZGoogleLogin] Error in onEntryComplete', [
'message' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
// エラーが発生してもセッションはクリア
try {
$request = $this->requestStack->getCurrentRequest();
if ($request && $request->hasSession()) {
$request->getSession()->remove(self::SESSION_GOOGLE_DATA);
}
} catch (\Exception $e2) {
// ignore
}
}
}
}