<?php
namespace Plugin\EventCalendar42\Controller;
use Carbon\Carbon;
use Eccube\Controller\AbstractController;
use Eccube\Repository\CalendarRepository;
use Eccube\Repository\BaseInfoRepository;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
use Plugin\EventCalendar42\Entity\EventCalendar;
use Plugin\EventCalendar42\Repository\EventCalendarRepository;
use Plugin\EventCalendar42\Form\Type\Admin\EventCalendarType;
class EventCalendarController extends AbstractController
{
/**
* @var CalendarRepository
*/
protected $calendarRepository;
/**
* @var EventCalendarRepository
*/
protected $eventCalendarRepository;
/**
* @var BaseInfoRepository
*/
protected $baseInfoRepository;
/**
* PageController constructor.
*
* @param CalendarRepository $calendarRepository
* @param EventCalendarRepository $eventCalendarRepository
* @param BaseInfoRepository $baseInfoRepository
*/
public function __construct(
CalendarRepository $calendarRepository,
EventCalendarRepository $eventCalendarRepository,
BaseInfoRepository $baseInfoRepository
) {
$this->calendarRepository = $calendarRepository;
$this->eventCalendarRepository = $eventCalendarRepository;
$this->baseInfoRepository = $baseInfoRepository;
}
/**
* @Route("/block/event_calendar", name="block_event_calendar", methods={"GET"})
* @Template("Block/event_calendar.twig")
*/
public function block(Request $request)
{
$today = Carbon::now();
$year = $today -> year;
$month = $today -> month;
// $basedate = Carbon::createFromDate($year, $month, 1);
$firstDateOfThisMonth = $today->copy()->startOfMonth();
$endDateOfThisMonth = $today->copy()->endOfMonth();
// 今月のカレンダー配列を取得
$thisMonthCalendar = $this->createCalendar($firstDateOfThisMonth);
// 【定休日カレンダー設定】今月の定休日を取得
$HolidaysOfThisMonth = $this->calendarRepository->getHolidayList($firstDateOfThisMonth, $endDateOfThisMonth);
// 【定休日カレンダー設定】定休日リストを取得
$holidayListOfThisMonth = [];
foreach ($HolidaysOfThisMonth as $Holiday) {
$holidayListOfThisMonth[] = $Holiday->getHoliday();
}
// 【定休日カレンダー設定】今月のカレンダー配列に定休日フラグを設定
$thisMonthCalendar = $this->setHolidayAndTodayFlag($thisMonthCalendar, $holidayListOfThisMonth, $today->copy());
// 各カレンダータイトルを作成
$monthFormat = $this->translator->trans('front.block.calendar.month_format');
$thisMonthTitle = $firstDateOfThisMonth->format($monthFormat);
// $Calendars = $this->calendarRepository->findAll();
return [
// 'Calendars' => $Calendars,
'ThisMonthTitle' => $thisMonthTitle,
'ThisMonthCalendar' => $thisMonthCalendar,
];
}
/**
* 一覧画面.
*
* @Route("/event", name="event_index", methods={"GET"})
* @Template("EventCalendar42/index.twig")
*/
public function index(Request $request)
{
$today = Carbon::now();
$year = $today -> year;
$month = $today -> month;
// $basedate = Carbon::createFromDate($year, $month, 1);
$firstDateOfThisMonth = $today->copy()->startOfMonth();
$endDateOfThisMonth = $today->copy()->endOfMonth();
// 今月のカレンダー配列を取得
$thisMonthCalendar = $this->createCalendar($firstDateOfThisMonth);
// 今月の定休日を取得
$HolidaysOfThisMonth = $this->calendarRepository->getHolidayList($firstDateOfThisMonth, $endDateOfThisMonth);
// 定休日リストを取得
$holidayListOfThisMonth = [];
foreach ($HolidaysOfThisMonth as $Holiday) {
$holidayListOfThisMonth[] = $Holiday->getHoliday();
}
// 今月のカレンダー配列に定休日フラグを設定
$thisMonthCalendar = $this->setHolidayAndTodayFlag($thisMonthCalendar, $holidayListOfThisMonth, $today->copy());
// 各カレンダータイトルを作成
$monthFormat = $this->translator->trans('front.block.calendar.month_format');
$thisMonthTitle = $firstDateOfThisMonth->format($monthFormat);
$changeMonth = Carbon::createFromDate($year,$month,1);
$beforeMonth = $changeMonth->copy()->subMonth()->startOfMonth();
$beforeY = $beforeMonth->year;
$beforeM = $beforeMonth->month;
$nextMonth = $changeMonth->copy()->addMonth()->startOfMonth();
$nextY = $nextMonth->year;
$nextM = $nextMonth->month;
$url = $_SERVER['REQUEST_URI'];
$pattern = "/[\?&]([^&]+)=([^&#]+)/";
preg_match_all($pattern, $url, $matches);
if ($_SERVER['QUERY_STRING']) {
$queries = [];
$size = count($matches[0]);
for($i = 0; $i < $size; $i++){
$key = $matches[1][$i];
$value = $matches[2][$i];
$queries[$key] = $value;
}
$changeMonth = Carbon::createFromDate($queries['year'],$queries['month'],1);
$firstDateOfChangeMonth = $changeMonth->copy()->startOfMonth();
$endDateOfChangeMonth = $changeMonth->copy()->endOfMonth();
//1ヶ月前
$beforeMonth = $changeMonth->copy()->subMonth()->startOfMonth();
$beforeY = $beforeMonth->year;
$beforeM = $beforeMonth->month;
//1ヶ月後
$nextMonth = $changeMonth->copy()->addMonth()->startOfMonth();
$nextY = $nextMonth->year;
$nextM = $nextMonth->month;
$thisMonthCalendar = $this->createCalendar($changeMonth);
$thisMonthTitle = $changeMonth->format($monthFormat);
// 今月の定休日を取得
$HolidaysOfChangeMonth = $this->calendarRepository->getHolidayList($firstDateOfChangeMonth, $endDateOfChangeMonth);
// 定休日リストを取得
$holidayListOfChangeMonth = [];
foreach ($HolidaysOfChangeMonth as $Holiday) {
$holidayListOfChangeMonth[] = $Holiday->getHoliday();
}
// 今月のカレンダー配列に定休日フラグを設定
$thisMonthCalendar = $this->setHolidayAndTodayFlag($thisMonthCalendar, $holidayListOfChangeMonth, $changeMonth);
}
// イベント一覧ページの重複しないイベントリスト
$eventIntro = [];
$eventLists = [];
foreach($thisMonthCalendar as $calendar){
if($calendar['events']){
foreach( $calendar['events'] as $event) {
if($event) {
$eventIntro[$event['id']] = $event;
}
}
}
}
if($eventIntro){
$eventLists = $this->sortByKey('start_date', SORT_ASC, $eventIntro);
}
// イベント一覧を取得する
$eventLists = $this->eventCalendarRepository->findBy(['is_active' => true], ['start_date' => 'asc']);
return [
// 'pagination' => $Events,
'ThisMonthTitle' => $thisMonthTitle,
'ThisMonthCalendar' => $thisMonthCalendar,
'beforeY' => $beforeY,
'beforeM' => $beforeM,
'nextY' => $nextY,
'nextM' => $nextM,
'eventLists' => $eventLists,
];
}
/**
* 詳細画面.
*
* @Route("/event/detail/{id}", name="event_detail", requirements={"id":"\d+"})
* @Template("EventCalendar42/detail.twig")
*
*/
// public function edit(Request $request, $id=null)
// {
// $Event = $this->eventCalendarRepository->find($id);
// //404設定
// if(!$Event || $Event->getIsActive() == false){
// throw new NotFoundHttpException();
// }
// return [
// 'event' => $Event,
// ];
// }
/**
* カレンダー配列に定休日と今日フラグを設定します
*
* @param array $targetMonthCalendar カレンダー配列
* @param array $holidayListOfThisMonths 定休日リスト
* @param array $baseHolidaysOfThisMonth 定休日リスト【基本設定】
* @param Carbon $targetDate ターゲット日
*
* @return array カレンダーの配列
*/
private function setHolidayAndTodayFlag($targetMonthCalendar, $holidayListOfThisMonths, Carbon $targetDate)
{
$today = Carbon::now();
// 【基本設定】今月の定休日を取得
$baseHolidaysOfThisMonth = $this->baseInfoRepository->get()->getRegularHoliday();
for ($i = 0; $i < count($targetMonthCalendar); $i++) {
// カレンダー配列の日が空の場合は処理をスキップ
if ($targetMonthCalendar[$i]['day'] == '') {
$targetMonthCalendar[$i]['holiday'] = false;
$targetMonthCalendar[$i]['baseholiday'] = false;
$targetMonthCalendar[$i]['today'] = false;
continue;
}
$targetYmdDateTime = new \DateTime($targetDate->copy()->format('Y-n').'-'.$targetMonthCalendar[$i]['day']);
$targetw = $targetYmdDateTime->format('w');
if($targetYmdDateTime){
// カレンダーの日付が定休日リストに存在するかを確認
$result = array_search($targetYmdDateTime, $holidayListOfThisMonths);
// 定休日フラグを設定
if ($result !== false) {
$targetMonthCalendar[$i]['holiday'] = true;
} else {
$targetMonthCalendar[$i]['holiday'] = false;
}
}else{
$targetMonthCalendar[$i]['holiday'] = false;
}
// 今日フラグを設定
if ($targetYmdDateTime == new \DateTime($today->copy()->format('Y-n-j'))) {
$targetMonthCalendar[$i]['today'] = true;
} else {
$targetMonthCalendar[$i]['today'] = false;
}
if($baseHolidaysOfThisMonth){
// 【基本設定】カレンダーの曜日が定休日リストに存在するかを確認
$result2 = array_search($targetw, $baseHolidaysOfThisMonth);
// 定休日フラグを設定
if ($result2 !== false) {
$targetMonthCalendar[$i]['baseholiday'] = true;
} else {
$targetMonthCalendar[$i]['baseholiday'] = false;
}
}else{
$targetMonthCalendar[$i]['baseholiday'] = false;
}
}
return $targetMonthCalendar;
}
/**
* カレンダーの配列を生成します
*
* @param Carbon $firstDateOfTargetMonth 月初日
*
* @return array カレンダーの配列
*/
private function createCalendar(Carbon $firstDateOfTargetMonth)
{
$year = $firstDateOfTargetMonth->year;
$month = $firstDateOfTargetMonth->month;
$Events = $this->eventCalendarRepository->findBy([],['start_date' => 'desc']);
// 週のうちの何日目か 0 (日曜)から 6 (土曜)を取得
$firstDayOfWeek = $firstDateOfTargetMonth->dayOfWeek;
$targetMonthCalendar = [];
// 1日目の曜日の位置手前まで空文字を追加
for ($i = 0; $i <= $firstDayOfWeek; $i++) {
$targetMonthCalendar[$i]['day'] = '';
$targetMonthCalendar[$i]['dayOfWeek'] = '';
$targetMonthCalendar[$i]['dateTime'] = '';
$targetMonthCalendar[$i]['events'] = array();
}
// 1日目の曜日の位置+月の日数
$loopCount = $firstDayOfWeek + $firstDateOfTargetMonth->daysInMonth;
// 月の日数に合わせて日と曜日を追加
$dayNumber = 1;
$dayOfWeekNumber = $firstDayOfWeek;
for ($i = $firstDayOfWeek; $i < $loopCount; $i++) {
// $dateTime = new \DateTime($firstDateOfTargetMonth->copy()->format('Y-n').'-'.$dayNumber);
$dateTime = new \DateTime($firstDateOfTargetMonth->format('Y-n-'.$dayNumber.' 00:00'));
$startTime = new \DateTime($firstDateOfTargetMonth->format('Y-n-'.$dayNumber.' 23:59'));
$targetMonthCalendar[$i]['day'] = $dayNumber;
$targetMonthCalendar[$i]['dayOfWeek'] = $this->getDayOfWeekString($dayOfWeekNumber);
$targetMonthCalendar[$i]['dateTime'] = $dateTime;
$targetMonthCalendar[$i]['events'] = array();
// $targetMonthCalendar[$i]['dateTime'] = Carbon::createFromDate($year, $month, $dayNumber);
foreach($Events as $event){
$startDate = '';
$endDate = '';
$startDate = new \DateTime($event['start_date']->format('Y-n-j H:i'));
$endDate = new \DateTime($event['end_date']->format('Y-n-j H:i'));
if($startDate <= $startTime && $dateTime <= $endDate){
// $startDate = $startDate->format('Y年n月j日');
// $endDate = $endDate->format('Y年n月j日');
array_push($targetMonthCalendar[$i]['events'],
array(
'id' => $event['id'],
'title' => $event['title'],
'icon' => $event['icon'],
'url' => $event['url'],
'link_method' => $event['link_method'],
'is_active' => $event['is_active'],
'type' => $event['type'],
'start_date' => $event['start_date'],
'end_date' => $event['end_date'],
'free_area' => $event['free_area']
));
}
}
$dayNumber++;
$dayOfWeekNumber++;
// 曜日のおりかえし: 0 (日曜)へ
if ($dayOfWeekNumber == 7) {
$dayOfWeekNumber = 0;
}
}
// 1日目の曜日の位置+月の日数に合わせて後に空文字を追加
// 7日*4週=28日(日曜始まりでうるう年じゃない2月)
if ($loopCount === 28) {
// 後に空文字追加はスキップ
return $targetMonthCalendar;
}
// 7日*6週=42日、7日*5週=35日
$paddingLoopCount = 35;
if ($loopCount > 35) {
$paddingLoopCount = 42;
}
for ($i = $loopCount; $i < $paddingLoopCount; $i++) {
$targetMonthCalendar[$i]['day'] = '';
$targetMonthCalendar[$i]['dayOfWeek'] = '';
$targetMonthCalendar[$i]['dateTime'] = '';
$targetMonthCalendar[$i]['events'] = array();
}
return $targetMonthCalendar;
}
/**
* 曜日を数値から文字列へ変換します
*
* @param int $dayOfWeekNumber 曜日の番号 : 0 (日曜)から 6 (土曜)
*
* @return string 曜日の文字 : Sun(日曜)からSat(土曜)
*/
private function getDayOfWeekString($dayOfWeekNumber)
{
$weekday = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
return $weekday[$dayOfWeekNumber];
}
//キーによるソートのための関数
function sortByKey($key_name, $sort_order, $array) {
foreach ($array as $key => $value) {
$standard_key_array[$key] = $value[$key_name];
}
array_multisort($standard_key_array, $sort_order, $array);
return $array;
}
}