<?php
namespace Plugin\PiaReservation\Controller;
use Eccube\Controller\AbstractController;
use Plugin\PiaReservation\Repository\PiaReservationRepository;
use Plugin\PiaReservation\Service\PiaReservationMailService;
use Plugin\PiaReservation\Form\Type\PiaReservationType;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
/**
* PiaReservationController
*
* @Route("/reservation")
*/
class PiaReservationController extends AbstractController
{
/**
* @var PiaReservationRepository
*/
protected $piaReservationRepository;
/**
* @var PiaReservationMailService
*/
protected $piaReservationMailService;
/**
* @var TokenStorageInterface
*/
protected $tokenStorage;
/**
* @var FormFactoryInterface
*/
protected $formFactory;
public function __construct(
PiaReservationRepository $piaReservationRepository,
PiaReservationMailService $piaReservationMailService,
TokenStorageInterface $tokenStorage,
FormFactoryInterface $formFactory
) {
$this->piaReservationRepository = $piaReservationRepository;
$this->piaReservationMailService = $piaReservationMailService;
$this->tokenStorage = $tokenStorage;
$this->formFactory = $formFactory;
}
/**
* 来店予約フォームを表示
* View: PiaReservation/default/index.twig
* URL: /reservation/
*
* @Route("/", name="plugin_pia_reservation")
*/
public function index(Request $request)
{
$errorMsg = [];
if ($request->getSession()->has('error_msg')) {
$errorMsg = $request->getSession()->get('error_msg');
$request->getSession()->remove('error_msg');
}
// ログイン情報を取得
$token = $this->tokenStorage->getToken();
$customer = $token && $token->getUser() ? $token->getUser() : null;
// 初期データを設定
$data = [];
if ($customer) {
$data = [
'reservation_name' => $customer->getName01() . ' ' . $customer->getName02(),
'reservation_email' => $customer->getEmail(),
'reservation_tel' => $customer->getPhoneNumber(),
];
}
// フォームを作成
$form = $this->formFactory->createBuilder(PiaReservationType::class, $data)->getForm();
$startDate = date("Y-m") . "-01";
$htRoku = [];
for ($i = 0; $i < 4; $i++) {
$month = date("Y-m", strtotime("+{$i} month", strtotime($startDate)));
$hash = $this->getHashRokuyou($month);
foreach ($hash as $k => $v) {
$htRoku[$k] = $v;
}
}
// 定休日一覧を取得
$holiday = $this->piaReservationRepository->getDispHoliday();
return $this->render('@PiaReservation/default/index.twig', [
'form' => $form->createView(),
'error_msg' => $errorMsg,
'holiday' => $holiday,
'htRoku' => $htRoku,
]);
}
/**
* 確認画面
* View: PiaReservation/default/confirm.twig
* URL: /reservation/confirm
*
* @Route("/confirm", name="plugin_pia_reservation_confirm")
*/
public function confirm(Request $request)
{
$params = $request->request->all();
$errorMsg = [];
// 登録処理
if (!empty($params["mode"]) && $params["mode"] == "regist") {
if (!$request->getSession()->has('params')) {
$errorMsg[] = "「戻るボタン」で戻った場合は最初からご入力ください。";
$request->getSession()->set('error_msg', $errorMsg);
return $this->redirectToRoute('plugin_pia_reservation');
} else {
$params = $request->getSession()->get('params');
try {
$token = $this->tokenStorage->getToken();
$customerId = $token && $token->getUser() ? $token->getUser()->getId() : 0;
// 1. DBを登録
$data = $params;
$data["status"] = 1;
$data["hope_time01"] = empty($params["hope_time01"]) ? "" : $params["hope_time01"];
$data["hope_date02"] = empty($params["hope_date02"]) ? "" : $params["hope_date02"];
$data["hope_time02"] = empty($params["hope_time02"]) ? "" : $params["hope_time02"];
$data["hope_date03"] = empty($params["hope_date03"]) ? "" : $params["hope_date03"];
$data["hope_time03"] = empty($params["hope_time03"]) ? "" : $params["hope_time03"];
$data["customer_id"] = $customerId;
$data["register_id"] = $customerId;
$data["update_id"] = $customerId;
$data["create_date"] = new \DateTime();
$data["update_date"] = new \DateTime();
$this->piaReservationRepository->save($data);
// 2. メールを送信
$this->piaReservationMailService->sendPiaReservationMail($data);
// 3. セッションの削除
$request->getSession()->remove('params');
// 4. スプレッドシートに登録
$this->saveSpreadSheet($params);
// 5. 完了画面の表示
return $this->redirectToRoute('plugin_pia_reservation_complete');
} catch (\Exception $ex) {
$errorMsg[] = $ex->getMessage();
$request->getSession()->set('error_msg', $errorMsg);
return $this->redirectToRoute('plugin_pia_reservation');
}
}
}
// フォームの処理
$form = $this->formFactory->createBuilder(PiaReservationType::class)->getForm();
$form->handleRequest($request);
// フォームが送信された場合
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
// DateTimeオブジェクトを文字列に変換
if ($data['hope_date01'] instanceof \DateTime) {
$data['hope_date01'] = $data['hope_date01']->format('Y-m-d');
}
if ($data['hope_date02'] instanceof \DateTime) {
$data['hope_date02'] = $data['hope_date02']->format('Y-m-d');
}
if ($data['hope_date03'] instanceof \DateTime) {
$data['hope_date03'] = $data['hope_date03']->format('Y-m-d');
}
$request->getSession()->set('params', $data);
return $this->render('@PiaReservation/default/confirm.twig', ['params' => $data]);
}
// フォームが無効な場合、エラーを表示
if ($form->isSubmitted() && !$form->isValid()) {
$errorMsg[] = "入力内容に誤りがあります。";
$request->getSession()->set('error_msg', $errorMsg);
return $this->redirectToRoute('plugin_pia_reservation');
}
// 通常のバリデーション(フォームを使用しない場合のフォールバック)
if (empty($params["hope_date01"])) {
$errorMsg[] = "第1希望日を選択してください。";
}
if (empty($params["reservation_name"])) {
$errorMsg[] = "お名前を入力してください。";
}
if (empty($params["reservation_tel"])) {
$errorMsg[] = "電話番号を入力してください。";
}
if (empty($params["reservation_email"])) {
$errorMsg[] = "メールアドレスを入力してください。";
}
if (count($errorMsg) > 0) {
$request->getSession()->set('error_msg', $errorMsg);
return $this->redirectToRoute('plugin_pia_reservation');
}
// DateTimeオブジェクトを文字列に変換(フォールバック処理用)
if (isset($params['hope_date01']) && $params['hope_date01'] instanceof \DateTime) {
$params['hope_date01'] = $params['hope_date01']->format('Y-m-d');
}
if (isset($params['hope_date02']) && $params['hope_date02'] instanceof \DateTime) {
$params['hope_date02'] = $params['hope_date02']->format('Y-m-d');
}
if (isset($params['hope_date03']) && $params['hope_date03'] instanceof \DateTime) {
$params['hope_date03'] = $params['hope_date03']->format('Y-m-d');
}
$request->getSession()->set('params', $params);
return $this->render('@PiaReservation/default/confirm.twig', ['params' => $params]);
}
/**
* 完了画面
* View: PiaReservation/default/complete.twig
* URL: /reservation/complete
*
* @Route("/complete", name="plugin_pia_reservation_complete")
*/
public function complete()
{
return $this->render('@PiaReservation/default/complete.twig');
}
/**
* スプレッドシートに保存
*
* @param array $data
*/
private function saveSpreadSheet($data)
{
$keyFile = $this->getParameter('kernel.project_dir') . '/app/Library/vendor/coinpalace-form-appraisal-d0023a2a5631.json';
$autoloadFile = $this->getParameter('kernel.project_dir') . '/app/Library/vendor/autoload.php';
if (!file_exists($keyFile) || !file_exists($autoloadFile)) {
error_log('Google Sheets API key file or autoload.php not found');
return;
}
require_once $autoloadFile;
define('SCOPES', implode(' ', array(\Google_Service_Sheets::SPREADSHEETS)));
$client = new \Google_Client();
$client->setScopes(SCOPES);
$client->setAuthConfig($keyFile);
$sheet = new \Google_Service_Sheets($client);
$spreadsheetId = '1qBc9w5NkeiwOo814TyX1cUJ8RJnQgWzGYTPfi6Np94E';
// null値を空文字列に変換し、連続した配列インデックスを保証
$value = [];
$value[] = date("Y-m-d H:i:s");
$value[] = $data["hope_date01"] ?? '';
$value[] = $data["hope_time01"] ?? '';
$value[] = $data["hope_date02"] ?? '';
$value[] = $data["hope_time02"] ?? '';
$value[] = $data["hope_date03"] ?? '';
$value[] = $data["hope_time03"] ?? '';
$value[] = $data["reservation_name"] ?? '';
$value[] = $data["reservation_tel"] ?? '';
$value[] = $data["reservation_email"] ?? '';
$value[] = $data["visitor"] ?? '';
$value[] = $data["visitor_detail"] ?? '';
$value[] = $data["message"] ?? '';
// 配列を連続したインデックスに再構築(JSONでオブジェクトではなく配列として出力されるように)
$values = [array_values($value)];
$body = new \Google_Service_Sheets_ValueRange([
'values' => $values,
]);
$response = $sheet->spreadsheets_values->append(
$spreadsheetId,
'来店予約',
$body,
["valueInputOption" => 'USER_ENTERED']
);
}
/**
* 六曜をハッシュで取得
*
* @param string $month
* @return array
*/
public function getHashRokuyou($month)
{
list($year, $mon) = explode("-", $month);
$lastDay = date('d', mktime(0, 0, 0, intval($mon) + 1, 0, $year));
$hash = [];
$htNm = ['0' => '大安', '1' => '赤口', '2' => '先勝', '3' => '友引', '4' => '先負', '5' => '仏滅'];
for ($day = 1; $day <= $lastDay; $day++) {
$date = $year . "-" . $mon . "-" . sprintf("%02d", $day);
$no = $this->getRokuyou($year, $mon, $day);
$hash[$date] = empty($htNm[$no]) ? "" : $htNm[$no];
}
return $hash;
}
/**
* 六曜算出関数
*
* @param int $year
* @param int $mon
* @param int $day
* @return int
*/
public function getRokuyou($year, $mon, $day)
{
// 簡略化された六曜計算(実際の実装ではより複雑な計算が必要)
// ここでは日付の合計値から六曜を算出
$total = $year + $mon + $day;
return ($total % 6);
}
}