<?php
namespace App\Controller;
use App\Entity\Course;
use App\Repository\CourseRepository;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\HttpFoundation\Request;
use App\Repository\CourseOccurrenceRepository;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use App\Repository\CourseOccurrenceTimeRepository;
use Menke\UserBundle\Controller\AbstractClientableController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* @Route("/course/templates")
* @IsGranted("ROLE_MANAGER")
*/
class CourseTemplateController extends AbstractClientableController
{
const LISTING_LIMIT = null;
/**
* @Route("/convert/course/{courseId}/time/{timeId}", name="course-templates_convert", methods="GET")
*/
public function convert(Request $request, $courseId, CourseRepository $courseRepository): Response
{
return $this->render('course-template/convert.html.twig', [
]);
}
/**
* @Route("/", name="course-templates_index", methods="GET")
*/
public function index(CourseRepository $courseRepo)
{
// Fetch course templates
$courses = $courseRepo->findBy([
'courseNature' => 'CourseTemplate'
]);
return $this->render('course-template/index.html.twig', [
'courses' => $courses
]);
}
/**
* @Route("/{id}/proposals", name="course_template_proposals", methods="GET", requirements={"id"="\d+"})
*/
public function proposals(
Request $request,
Course $course,
CourseOccurrenceRepository $repo,
CourseOccurrenceTimeRepository $timesRepo
): Response
{
$this->denyAccessUnlessGranted('ROLE_MANAGER', $course);
// Set dates
$date = $request->get('date') ?? date('Y-m-d');
$dateTime = new \DateTime($date);
if (!empty($request->get('step'))) {
if ($request->get('step') == 'prev') {
$dateTime->modify('-1 month');
}
elseif ($request->get('step') == 'next') {
$dateTime->modify('+1 month');
}
$date = $dateTime->format('Y-m-d');
}
$occurrences = $repo->findByCoursePaged($course,1000);
$slots = [];
foreach ($occurrences as $occurence) {
$queryBuilder = $timesRepo->createQueryBuilder('cot');
$queryBuilder
->leftJoin('cot.occurrence', 'co')
->andWhere('co.id = :id')
->andWhere('DATE_FORMAT(cot.start, \'%Y-%m-%d\') >= :start')
->andWhere('DATE_FORMAT(cot.end, \'%Y-%m-%d\') <= :end')
->setParameter('id', $occurence->getId())
->setParameter('start', $dateTime->format('Y-m-01'))
->setParameter('end', $dateTime->format('Y-m-t'))
;
$times = $queryBuilder->getQuery()->getResult();
foreach ($times as $time) {
$occurence = $time->getOccurrence();
$course = $occurence->getCourse();
$slots[$time->getStart()->format('Y-m-d')][] = [
'id' => $time->getId(),
'availability' => $time->getAvailability(),
'orderItemId' => $time->getOrderItem(),
'occurence' => [
'id' => $occurence->getId(),
'start' => $time->getStart()->format('Y-m-d H:i:s'),
'end' => $time->getEnd()->format('Y-m-d H:i:s'),
],
'course' => [
'id' => $course->getId(),
'title' => $course->getTitle(),
]
];
}
}
// Get first day
$fistDayDate = new \DateTime($dateTime->format('Y-m-01'));
$firstDay = $fistDayDate->format('N');
$days = $dateTime->format('t');
$weeks = [];
$dayNum = 0;
for ($x = 0; $x < 50; ++$x) {
$weekIndex = floor($x / 7);
$value = (($x + 1) >= $firstDay && $dayNum < $days) ? ++$dayNum : null;
if ($x % 7 == 0 and $dayNum >= $days) {
break;
}
$key = $dateTime->format('Y-m-' . str_pad($dayNum, 2, '0', STR_PAD_LEFT));
$weeks[$weekIndex][] = [
'daynum' => $value,
'proposals' => ($value && !empty($slots[$key]) ? $slots[$key] : [])
];
}
$monthNames = [
1 => 'Januar',
2 => 'Februar',
3 => 'März',
4 => 'April',
5 => 'Mai',
6 => 'Juni',
7 => 'Juli',
8 => 'August',
9 => 'September',
10 => 'Oktober',
11 => 'November',
12 => 'Dezember',
];
return $this->render('course-template/proposals.html.twig', [
'course' => $course,
'date' => $date,
'monthName' => $monthNames[$dateTime->format('n')],
'weeks' => $weeks
]);
}
/**
* @Route("/{id}/proposals/modal/time/{timeId}/edit", name="course_template_proposals_modal_time_edit", methods="GET", requirements={"id"="\d+"})
*/
public function proposalsModalTimeEdit(
Request $request,
Course $course,
CourseOccurrenceTimeRepository $timesRepo
): Response
{
$this->denyAccessUnlessGranted('ROLE_MANAGER', $course);
// Fetch time
$time = $timesRepo->find($request->get('timeId'));
$source = $this->renderView('course-template/modals/time-edit.html.twig', [
'course' => $course,
'time' => $time
]);
return new \Symfony\Component\HttpFoundation\JsonResponse([
'modal' => $source
]);
}
/**
* @Route("/{id}/proposals/modal/time/{timeId}/edit", name="course_template_proposals_time_update", methods="POST", requirements={"id"="\d+"})
*/
public function courseOccurrencesProposalsTimeUpdate(
Request $request,
Course $course,
CourseOccurrenceTimeRepository $timesRepo,
ManagerRegistry $managerRegistry
): Response
{
$this->denyAccessUnlessGranted('ROLE_MANAGER', $course);
// Fetch time
$time = $timesRepo->find($request->get('timeId'));
$time->setNote($request->get('note'));
$time->setAvailability($request->get('availability'));
$em = $managerRegistry->getManager();
$em->merge($time);
$em->flush();
return new \Symfony\Component\HttpFoundation\JsonResponse([
'dismissModal' => true,
'removeClass' => [ 'selector' => '.timeslot[data-time="' . $time->getId() . '"]', 'className' => 'Bookable Requestable NotAvailable' ],
'addClass' => [ 'selector' => '.timeslot[data-time="' . $time->getId() . '"]', 'className' => $time->getAvailability() ]
]);
}
/**
* @Route("/{id}/proposals/modal/time/{timeId}/unbook", name="course_template_proposals_time_unbook", methods="POST", requirements={"id"="\d+"})
*/
public function courseOccurrencesProposalsTimeUnbook(
Request $request,
Course $course,
CourseOccurrenceTimeRepository $timesRepo,
ManagerRegistry $managerRegistry
): RedirectResponse {
$this->denyAccessUnlessGranted('ROLE_MANAGER', $course);
// Fetch time
$time = $timesRepo->find($request->get('timeId'));
if (!$time) {
return new JsonResponse(['error' => 'Time not found'], 404);
}
$time->setNote('unbooked');
$time->setAvailability('Bookable');
$time->setModified(new \DateTime());
$em = $managerRegistry->getManager();
$em->merge($time);
$em->flush();
$time = $timesRepo->find($request->get('timeId'));
$this->addFlash('notice', 'Der Termin wurde freigegeben');
return $this->redirectToRoute('course_template_proposals', [
'id' => $course->getId(),
]);
}
}