<?php
namespace App\Controller;
use App\Entity\AccountRole;
use App\Entity\AccountType;
use App\Entity\Address;
use App\Entity\Applicant;
use App\Entity\City;
use App\Entity\Course;
use App\Entity\CourseRegistrationRequest;
use App\Entity\CourseReview;
use App\Entity\CourseState;
use App\Entity\CourseTerm;
use App\Entity\CourseTopic;
use App\Entity\District;
use App\Entity\Organizer;
use App\Entity\Region;
use App\Entity\SonataUserUser;
use App\Form\CourseRegistrationCompanyRequestType;
use App\Form\CourseRegistrationRequestType;
use App\Form\CourseReviewType;
use App\Form\CourseTermType;
use App\Form\CourseType;
use App\Form\ImportFileType;
use App\Repository\AttributeGroupRepository;
use App\Repository\CertificationRepository;
use App\Repository\CityRepository;
use App\Repository\CourseLengthRepository;
use App\Repository\CourseProgressLevelRepository;
use App\Repository\CourseRepository;
use App\Repository\CourseTermRepository;
use App\Repository\DistrictRepository;
use App\Repository\LanguageLevelRepository;
use App\Repository\RegionRepository;
use App\Repository\TargetGroupRepository;
use App\Repository\TeachingTypeRepository;
use App\Util\AddressUtil;
use App\Util\ApplicantUtil;
use App\Util\CourseImportValidator;
use App\Util\CourseUtil;
use App\Util\EmailUtil;
use App\Util\LogUtil;
use App\Util\OrganizerUtil;
use App\Util\StatsUtil;
use App\Util\UserUtil;
use Knp\Component\Pager\PaginatorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sonata\UserBundle\Model\UserInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route("/kurzy")
*/
class CourseController extends AbstractController
{
/**
* @var OrganizerUtil
*/
private $organizerUtil;
/**
* @var ApplicantUtil
*/
private $applicantUtil;
public function __construct(OrganizerUtil $organizerUtil, ApplicantUtil $applicantUtil)
{
$this->organizerUtil = $organizerUtil;
$this->applicantUtil = $applicantUtil;
}
/**
* @return Organizer
*/
private function getOrganizer()
{
$user = $this->getUser();
if (!$user instanceof UserInterface) {
throw $this->createAccessDeniedException();
}
$organizer = $this->organizerUtil->getOrganizerByUser($user);
if (!$organizer instanceof Organizer) {
throw $this->createAccessDeniedException();
}
return $organizer;
}
/**
* @return Organizer
*/
private function getApplicant()
{
$user = $this->getUser();
$applicant = $this->applicantUtil->getApplicantByUser($user);
if (!$applicant instanceof Applicant) {
return null;
}
return $applicant;
}
/**
* @Route("/", name="course_index", methods={"GET"})
*/
public function index(CourseRepository $courseRepository): Response
{
return $this->render('course/index.html.twig', [
'courses' => $courseRepository->findAll(),
]);
}
/**
* @Route("/new", name="course_new", methods={"GET","POST"})
*/
public function new(Request $request): Response
{
$course = new Course();
$course->setOrganizer($this->getOrganizer());
$form = $this->createForm(CourseType::class, $course);
$step = $course->getLastStep();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid() && $form->get('save')->isClicked()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($course);
$entityManager->flush();
return $this->redirectToRoute('dashboard');
}
if ($form->isSubmitted() && $form->isValid() && $form->get('save')->isClicked()) {
$course->setLastStep($step + 1);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($course);
$entityManager->flush();
return $this->redirectToRoute('dashboard');
}
if ($form->isSubmitted() && $form->isValid() && $form->get('continue')->isClicked()) {
$course->setLastStep($step + 1);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($course);
$entityManager->flush();
return $this->redirectToRoute('course_edit', ['id' => $course->getId()]);
}
$template = $request->isXmlHttpRequest() ? '_form.html.twig' : 'new.html.twig';
return $this->render('course/' . $template, [
'course' => $course,
'step' => $step,
'organizer' => $this->getOrganizer(),
'form' => $form->createView(),
]);
}
/**
* @Route("/new-import", name="course_new_import", methods={"GET", "POST"})
*/
public function newImport(Request $request,RegionRepository $regionRepository,
DistrictRepository $districtRepository,
CityRepository $cityRepository,
CourseProgressLevelRepository $courseProgressLevelRepository,
LanguageLevelRepository $languageLevelRepository,
CourseLengthRepository $courseLengthRepository,
AttributeGroupRepository $attributeGroupRepository,
TeachingTypeRepository $teachingTypeRepository,
TargetGroupRepository $targetGroupRepository,
CertificationRepository $certificationRepository,
CourseImportValidator $validator
): Response
{
$form = $this->createForm(ImportFileType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$importFile = $form->get('importFile')->getData();
if ($importFile) {
$originalFilename = pathinfo($importFile->getClientOriginalName(), PATHINFO_FILENAME);
$newFilename = uniqid().'.'.$importFile->guessExtension();
try {
$importFile->move(
$this->getParameter('kernel.project_dir') . '/var/imports',
$newFilename
);
} catch (FileException $e) {
$this->addFlash('danger', 'Chyba při nahrávání souboru.');
return $this->redirectToRoute('course_new_import');
}
$this->addFlash('success', 'Soubor byl úspěšně nahrán a uložen jako ' . $newFilename);
$fullPath = $this->getParameter('kernel.project_dir') . '/var/imports/' . $newFilename;
// Tady bude naše nová validační třída
$errors = $validator->validateFromOrganizerCsv($fullPath);
// Předáme chyby do session pro zobrazení
if (!empty($errors)) {
$this->addFlash('danger', 'V souboru byly nalezeny chyby.');
$request->getSession()->set('import_errors', $errors);
} else {
$this->addFlash('success', 'Soubor byl úspěšně ověřen – žádné chyby nenalezeny.');
}
return $this->redirectToRoute('course_new_import');
}
}
return $this->render('course/import.html.twig', [
'form' => $form->createView(),
'districts' => $districtRepository->findBy([], ['name' => 'ASC']),
'regions' => $regionRepository->findBy([], ['name' => 'ASC']),
'progressLevels' => $courseProgressLevelRepository->findBy([], ['name' => 'ASC']),
'languageLevels' => $languageLevelRepository->findBy([], ['name' => 'ASC']),
'courseLengths' => $courseLengthRepository->findBy([], ['name' => 'ASC']),
'attributeGroups' => $attributeGroupRepository->findBy([], ['name' => 'ASC']),
'teachingTypes' => $teachingTypeRepository->findBy([], ['name' => 'ASC']),
'targetGroups' => $targetGroupRepository->findBy([], ['name' => 'ASC']),
'certifications' => $certificationRepository->findBy([], ['name' => 'ASC']),
]);
}
/**
* @Route("/{id}/terms/new", name="course_terms_new", methods={"GET","POST"})
*/
public function newTerm(Request $request, Course $course, CourseUtil $courseUtil): Response
{
$courseTerm = new CourseTerm();
$courseTerm->setPublishedAt(new \DateTime());
$courseTerm->setState($courseUtil->getCourseStateByIdentifier(CourseState::COURSE_STATE_DRAFT));
$form = $this->createForm(CourseTermType::class, $courseTerm);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$course->addTerm($courseTerm);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($course);
$entityManager->flush();
return $this->redirectToRoute('dashboard');
}
return $this->render('course/terms.new.html.twig', [
'course' => $course,
'courseTerm' => $courseTerm,
'form' => $form->createView(),
]);
}
/**
* @Route("/{id}/registrace", name="course_registration", methods={"GET","POST"})
*/
public function registration(CourseTerm $courseTerm, Request $request, EmailUtil $emailUtil, UserUtil $userUtil, LogUtil $logUtil): Response
{
$course = $courseTerm->getCourse();
$courseRegistration = new CourseRegistrationRequest();
$courseRegistration->setCourseTerm($courseTerm);
$applicant = $this->getApplicant();
if ($applicant instanceof Applicant) {
$courseRegistration->setApplicant($applicant);
if ($applicant->getAddress() instanceof Address) {
$address = clone $applicant->getAddress();
$courseRegistration->setAddress($address);
}
}
//
$form = $this->createForm(CourseRegistrationRequestType::class, $courseRegistration);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid() && $form->get('save')->isClicked()) {
/** @var CourseRegistrationRequest $data */
$data = $form->getData();
if (!$applicant instanceof Applicant) {
$newUser = new SonataUserUser();
$newUser->setAccountRole($userUtil->getAccountRoleByIdentifier(AccountRole::ACCOUNT_ROLE_APPLICANT));
$newUser->setAccountType($userUtil->getAccountTypeByIdentifier(AccountType::ACCOUNT_TYPE_INDIVIDUAL));
$newUser->setUsername($data->getEmail());
$newUser->setEmail($data->getEmail());
$newUser->setFirstname($data->getFirstname());
$newUser->setLastname($data->getLastname());
$newUser->setPhone($data->getPhone());
$newUser->setPlainPassword($userUtil->generatePassword());
$newUser->setEnabled(true);
$newUser->setEmailPublic($newUser->getEmail());
$this->addFlash('success', 'Byl Vám vytvořen uživatelský účet. Přihlašovací údaje Vám byly odeslány e-mailem');
$userUtil->createRoleData($newUser);
}
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($courseRegistration);
$entityManager->flush();
$this->addFlash('success', 'Registrace byla přijata');
$emailUtil->addEmailToQueueFromTemplateWithDataTransform($course->getOrganizer()->getUserAccount()->getEmail(), EmailUtil::REGISTRATION_REQUEST_PROMOTER, $courseRegistration);
$emailUtil->addEmailToQueueFromTemplateWithDataTransform($courseRegistration->getEmail(), EmailUtil::REGISTRATION_REQUEST_APPLICANT, $courseRegistration);
$logUtil->addNewMessage('Nový zájemce o kurz čeká na schválení registrace', 'registration_request', $courseRegistration->getId(), $courseRegistration->getCourseTerm()->getCourse());
return $this->redirectToRoute('course_show', ['id' => $course->getId()], Response::HTTP_SEE_OTHER);
}
$template = $request->isXmlHttpRequest() ? '_form.html.twig' : 'registration.html.twig';
return $this->render('course/' . $template, [
'course' => $course,
'courseTerm' => $courseTerm,
'courseRegistrationRequest' => $courseRegistration,
'form' => $form->createView(),
]);
}
/**
* @Route("/{id}/registrace-firma", name="course_registration_company", methods={"GET","POST"})
*/
public function registrationCompany(CourseTerm $courseTerm, Request $request, EmailUtil $emailUtil): Response
{
$course = $courseTerm->getCourse();
$courseRegistration = new CourseRegistrationRequest();
$courseRegistration->setCourseTerm($courseTerm);
$form = $this->createForm(CourseRegistrationCompanyRequestType::class, $courseRegistration);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid() && $form->get('save')->isClicked()) {
/** @var CourseRegistrationRequest $data */
$data = $form->getData();
$applicant = $data->getApplicant();
$courseRegistration->setApplicant($applicant);
if ($applicant->getAddress() instanceof Address) {
$address = clone $applicant->getAddress();
$courseRegistration->setAddress($address);
}
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($courseRegistration);
$entityManager->flush();
$this->addFlash('success', 'Registrace byla přijata');
$emailUtil->addEmailToQueueFromTemplateWithDataTransform($course->getOrganizer()->getUserAccount()->getEmail(), EmailUtil::REGISTRATION_REQUEST_PROMOTER, $courseRegistration);
$emailUtil->addEmailToQueueFromTemplateWithDataTransform($courseRegistration->getEmail(), EmailUtil::REGISTRATION_REQUEST_APPLICANT, $courseRegistration);
return $this->redirectToRoute('course_show', ['id' => $course->getId()], Response::HTTP_SEE_OTHER);
}
$template = $request->isXmlHttpRequest() ? '_form.html.twig' : 'registration_company.html.twig';
return $this->render('course/' . $template, [
'course' => $course,
'courseTerm' => $courseTerm,
'courseRegistrationRequest' => $courseRegistration,
'form' => $form->createView(),
]);
}
/**
* @Route("/{id}/pridat-hodnoceni", name="course_review_create", methods={"GET","POST"})
*/
public function reviewCreate(Course $course, Request $request, EmailUtil $emailUtil, LogUtil $logUtil): Response
{
$courseReview = new CourseReview();
$courseReview->setCourse($course);
$applicant = $this->getApplicant();
if ($applicant instanceof Applicant) {
$courseReview->setApplicant($applicant);
}
//
$form = $this->createForm(CourseReviewType::class, $courseReview);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid() && $form->get('save')->isClicked()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($courseReview);
$entityManager->flush();
$emailUtil->addEmailToQueueFromTemplateWithDataTransform($this->getUser()->getEmail(), EmailUtil::NEW_REVIEW_PROMOTER, $courseReview);
$this->addFlash('success', 'Recenze byla přijata');
$logUtil->addNewMessage('Obdrželi jste nové hodnocení u kurzu ' . $courseReview->getCourse()->getName(), 'review', $courseReview->getId(), $courseReview->getCourse());
return $this->redirectToRoute('course_show', ['id' => $course->getId()], Response::HTTP_SEE_OTHER);
}
$template = $request->isXmlHttpRequest() ? '_form.html.twig' : 'create.html.twig';
return $this->render('review/' . $template, [
'course' => $course,
'courseReview' => $courseReview,
'organizer' => $course->getOrganizer(),
'form' => $form->createView(),
]);
}
/**
* @Route("/{id}", name="course_show", methods={"GET"})
*/
public function show(Course $course, StatsUtil $statsUtil): Response
{
$statsUtil->saveStatsForCourse($course);
return $this->render('course/show.html.twig', [
'course' => $course,
]);
}
/**
* @Route("/{id}/podobne", name="course_alternative", methods={"GET"})
*/
public function alternative(Course $course, CourseRepository $courseRepository): Response
{
$courses = $courseRepository->findAlternative($course);
return $this->render('course/alternative.html.twig', [
'course' => $course,
'courses' => $courses
]);
}
/**
* @Route("/{id}/edit", name="course_edit", methods={"GET","POST"})
*/
public function edit(Request $request, Course $course): Response
{
if ($request->query->has('step')) {
$course->setLastStep($request->query->getInt('step'));
}
$organizer = $this->getOrganizer();
if ($organizer->getId() != $course->getOrganizer()->getId()) {
throw $this->createAccessDeniedException();
}
$form = $this->createForm(CourseType::class, $course);
$form->handleRequest($request);
$step = $course->getLastStep();
if ($form->isSubmitted() && $form->isValid() && $form->get('save')->isClicked()) {
$course->setLastStep($step + 1);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($course);
$entityManager->flush();
return $this->redirectToRoute('dashboard');
}
if ($form->isSubmitted() && $form->isValid() && $form->get('continue')->isClicked()) {
$course->setLastStep($step + 1);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($course);
$entityManager->flush();
return $this->redirectToRoute('course_edit', ['id' => $course->getId()]);
}
$template = $request->isXmlHttpRequest() ? '_form.html.twig' : 'edit.html.twig';
return $this->render('course/' . $template, [
'course' => $course,
'step' => $step,
'organizer' => $this->getOrganizer(),
'form' => $form->createView(),
]);
}
/**
* @Route("/{id}/cancel", name="course_cancel", methods={"GET","POST"})
*/
public function cancel(Request $request, Course $course, CourseUtil $courseUtil): Response
{
$organizer = $this->getOrganizer();
if ($organizer->getId() != $course->getOrganizer()->getId()) {
throw $this->createAccessDeniedException();
}
$course->setState($courseUtil->getCourseStateByIdentifier('canceled-by-organizer'));
$courseUtil->cancelCourseNotify($course);
$courseUtil->saveCourse($course);
return $this->redirectToRoute('dashboard');
}
/**
* @Route("/{id}/terms/{termId}/cancel", name="course_terms_cancel", methods={"GET","POST"})
*/
public function cancelTerms(Request $request, Course $course, int $termId, CourseUtil $courseUtil, CourseTermRepository $courseTermRepository): Response
{
$courseTerm = $courseTermRepository->find($termId);
$organizer = $this->getOrganizer();
if ($organizer->getId() != $course->getOrganizer()->getId()) {
throw $this->createAccessDeniedException();
}
$courseTerm->setState($courseUtil->getCourseStateByIdentifier('canceled-by-organizer'));
$courseUtil->cancelCourseTermNotify($courseTerm);
$courseUtil->saveCourseTerm($courseTerm);
return $this->redirectToRoute('dashboard');
}
/**
* @Route("/{id}/terms/{termId}/edit", name="course_terms_edit", methods={"GET","POST"}, requirements={"id" = "\d+","termId" = "\d+",})
*/
public function editTerm(Request $request, Course $course, int $termId, CourseTermRepository $courseTermRepository): Response
{
$courseTerm = $courseTermRepository->find($termId);
$organizer = $this->getOrganizer();
if ($organizer->getId() != $course->getOrganizer()->getId()) {
throw $this->createAccessDeniedException();
}
$form = $this->createForm(CourseTermType::class, $courseTerm);
$form->handleRequest($request);
$step = $course->getLastStep();
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($courseTerm);
$entityManager->flush();
return $this->redirectToRoute('dashboard');
}
return $this->render('course/terms.edit.html.twig', [
'course' => $course,
'courseTerm' => $courseTerm,
'form' => $form->createView(),
]);
}
/**
* @Route("/{id}/terms", name="course_terms_list", methods={"GET","POST"})
*/
public function termsList(Request $request, Course $course, PaginatorInterface $paginator): Response
{
return $this->render('course/terms.list.html.twig', [
'course' => $course,
]);
}
/**
* @Route("/{id}/terms/{termId}/registrations", name="course_terms_registrations", methods={"GET","POST"}, requirements={"id" = "\d+","termId" = "\d+",})
*/
public function termRegistrations(Request $request, Course $course, int $termId, CourseTermRepository $courseTermRepository): Response
{
$courseTerm = $courseTermRepository->find($termId);
return $this->render('course/terms.registrations.html.twig', [
'course' => $course,
'courseTerm' => $courseTerm,
]);
}
/**
* @Route("/{id}", name="course_delete", methods={"POST"})
*/
public function delete(Request $request, Course $course): Response
{
if ($this->isCsrfTokenValid('delete' . $course->getId(), $request->request->get('_token'))) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->remove($course);
$entityManager->flush();
}
return $this->redirectToRoute('course_index', [], Response::HTTP_SEE_OTHER);
}
/**
* @Route("/import/city", name="import_city")
*/
public function importCity(AddressUtil $addressUtil): Response
{
ini_set('max_execution_time', 600);
$country = $addressUtil->getCountryByIdentifier('cz');
$row = 1;
$startId = 1;
if (($handle = fopen("https://raw.githubusercontent.com/33bcdd/souradnice-mest/master/souradnice.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
if ($row == 1) {
$row++;
continue;
}
$regionName = $data[4];
$regionCode = $data[5];
$districtName = $data[2];
$districtCode = $data[3];
$cityName = $data[0];
$cityCode = $data[1];
$latitude = $data[7];
$longitude = $data[8];
$postcode = $data[6];
$id = $row + $startId;
$city = $addressUtil->getCity($id);
if ($city->getName() == $cityName && $city->getPostcode() == $postcode && $city->getLatitude() == $latitude && $city->getLongitude() == $longitude) {
$city->setIdentifier($cityCode);
$addressUtil->saveCity($city);
$row++;
continue;
}
dump($city->getName() == $cityName);
dump($city->getPostcode() == $postcode);
dump($city->getLatitude() == $latitude);
dump($city->getLongitude() == $longitude);
dump($city);
dump($data);
exit;
$cities = $addressUtil->getCityByName($cityName);
if (count($cities) <= 1) {
continue;
}
foreach ($cities as $city) {
if ($city->getLongitude() == $longitude && $city->getLongitude() == $longitude) {
$city->setPostcode($postcode);
$addressUtil->saveCity($city);
continue;
}
}
continue;
$region = $addressUtil->getRegionByIdentifier($regionCode);
if (!$region instanceof Region) {
$region = new Region();
$region->setName($regionName);
$region->setIdentifier($regionCode);
$region->setCountry($country);
$addressUtil->saveRegion($region);
}
$district = $addressUtil->getDistrictByIdentifier($districtCode);
if (!$district instanceof District) {
$district = new District();
$district->setName($districtName);
$district->setIdentifier($districtCode);
$district->setRegion($region);
$addressUtil->saveDistrict($district);
}
$city = new City();
$city->setName($cityName);
$city->setLatitude($latitude);
$city->setLongitude($longitude);
$city->setDistrict($district);
$addressUtil->saveCity($city);
}
fclose($handle);
}
die("AAAA");
}
}