<?php
namespace App\Controller\Page;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Address;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use App\Entity\User;
use App\Entity\Institution;
use App\Entity\Notification;
use App\Entity\Province;
use App\Entity\Project;
use App\Entity\Form;
use App\Entity\Consent;
use App\Entity\ConsentUser;
use App\Form\Type\PageUserRegisterType;
use App\Form\Type\PageUserPasswordType;
use App\Form\Type\PageUserResetPasswordType;
use App\Form\Type\InstitutionType;
use App\Service\FreshMailService;
use App\Service\InstitutionService;
use Symfony\Component\HttpFoundation\Cookie;
use Knp\Component\Pager\PaginatorInterface;
class PageAuthController extends AbstractController
{
private $paginator;
public function __construct(PaginatorInterface $paginator){
$this->paginator = $paginator;
}
/**
* @Route("/", name="pageAuthLogin")
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
if($this->getUser()) {
return $this->redirectToRoute('pageDashboardIndex');
}
$error = $authenticationUtils->getLastAuthenticationError();
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('page/auth/login.html.twig', [
'last_username' =>$lastUsername,
'error' => $error
]);
}
/**
* @Route("/rejestracja", name="pageAuthRegister")
*/
public function register(Request $request, MailerInterface $mailer, FreshMailService $freshMailService): Response
{
$error = '';
$em = $this->getDoctrine()->getManager();
if($this->getUser()) {
return $this->redirectToRoute('pageDashboardIndex');
}
$consents = $this->getDoctrine()->getRepository(Consent::class)->findBy([
'isDeleted' => false
]);
$user = new User;
$user
->setRole('ROLE_USER')
->setStatus('INACTIVE')
->setHash(hash('sha256', uniqid()))
->setDateRegister(new \Datetime);
$form = $this->createForm(PageUserRegisterType::class, $user, [
'consents' => $consents
]);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid() ) {
$type = $form->get("type")->getData();
if ($type === 'project') {
if ($institutionId = (int) $request->request->get('institution_id')) {
$institution = $this->getDoctrine()->getRepository(Institution::class)->find($institutionId);
}
if (!isset($institution) || !$institution){
$error = 'Musisz wybrać placówkę';
} else {
$notificationType = null;
if ($institution->getTarget()) {
$notificationType = 2; // Rejestracja do placówki ze zmianą danych
} else if ($institution->getStatus() == 'INACTIVE') {
$notificationType = 1; // Rejestracja do nowej placówki
} else if ($institution->getStatus() == 'ACTIVE') {
$notificationType = 3; // Rejestracja do istniejącej placówki
}
if ($notificationType === 3) {
// Gdy użytkownik rejestruje się do istniejącej placówki, nie potrzebna jest akceptacja administratora
$user->setStatus('ACTIVE');
$user->addInstitution($institution);
} else {
// Tworzone jest zgłoszenie do administratora
$notification = new Notification;
$notification
->setUser($user)
->setInstitution($institution)
->setDateCreated(new \Datetime)
->setType($notificationType)
->setStatus('NEW');
$em->persist($notification);
}
}
} else {
$user->setStatus('ACTIVE');
}
// Zapisanie zaznaczonych zgód
$checkedConsents = $form->get("consents")->getData();
if ($checkedConsents && is_array($checkedConsents)) {
foreach ($checkedConsents as $checkedConsent) {
if ($consent = $this->getDoctrine()->getRepository(Consent::class)->find((int) $checkedConsent)) {
$consentUser = new ConsentUser;
$consentUser
->setConsenst($consent)
->setUser($user)
->setDate(new \Datetime);
$em->persist($consentUser);
if (strpos($consent->getDescription(), 'newsletter') !== false) {
$freshMailService->addSubscriber($user->getEmail());
}
}
}
}
// ===
if ($error === '') {
$em->persist($user);
$em->flush();
$link = $request->getScheme() . '://' . $request->getHttpHost() . '/ustaw-haslo/' . $user->getHash();
$title = "Witamy w serwisie CAŁA POLSKA CZYTA DZIECIOM!";
$email = (new TemplatedEmail())
->to(new Address($user->getEmail(), $user->getName() . ' ' . $user->getSurname()))
->subject($title)
->htmlTemplate('email/register.html.twig')
->context([
'title' => $title,
'link' => $link
]);
$mailer->send($email);
$this->addFlash('success', 'Konto zostało utworzone. Na podany adres e-mail został wysłany link do utworzenia hasła.');
return $this->redirectToRoute('pageAuthLogin');
}
}
// return $this->render('page/auth/register-old.html.twig', [
return $this->render('page/auth/register.html.twig', [
'form' => $form->createView(),
'error' => $error,
'user' => $user,
'provinces' => $this->getDoctrine()->getRepository(Province::class)->findAll()
]);
}
/**
* @Route("/rejestracja/data/placowki", name="PageAuthRegisterInstitutionsJson")
*/
public function listDataTable(Request $request): Response {
$page = $_GET["page"];
$orderCol = $request->request->get("order")[0]["column"];
$orderDir = $request->request->get("order")[0]["dir"];
$elForPage = $request->request->get("length");
$search = $request->request->get("search")["value"];
$institutions = $this->paginator->paginate(
$this->getDoctrine()->getRepository(Institution::class)->getInstitutionsForDataTable(
$orderCol, $orderDir, $search,
($_GET["name"]) ? $_GET["name"] : null,
($_GET["place"]) ? $_GET["place"] : null,
($_GET["province"]) ? $_GET["province"] : null,
($_GET["district"]) ? $_GET["district"] : null,
($_GET["commune"]) ? $_GET["commune"] : null,
($_GET["category"]) ? $_GET["category"] : null
), $page, $elForPage
);
$data = $this->InstitutionForDataTable($institutions);
return new JsonResponse(
array(
'draw' => $request->request->get("draw"),
'data' => $data,
'recordsFiltered' => $institutions->getTotalItemCount(),
'recordsTotal' => $institutions->getTotalItemCount()
)
, 200);
}
public function InstitutionForDataTable($institutions){
$data[0] = array("", "", "", "", "", "");
$i = 0;
if($institutions){
foreach($institutions->getItems() as $obj){
$pathShow = $this->generateUrl('adminInstitutionView', ['institutionId' => $obj->getId()]);
$pathAdmin = $this->generateUrl('adminInstitutionEdit', ['institutionId' => $obj->getId()]);
$streetAndNumbers = $obj->getStreet().' '.$obj->getBuilding();
if($obj->getLocalNumber()){
$streetAndNumbers.= " / ".$obj->getLocalNumber();
}
$buttons = '
<div class="text-nowrap">
<a href="javascript:;" title="Edytuj dane placówki" onclick="institutions.add(' .$obj->getId(). ')"><i class="fa fa-edit"></i></a>
<a href="javascript:;" title="Przypisz placówkę" onclick="institutions.change(' .$obj->getId(). ')"><i class="fa fa-plus-square-o"></i></a>
</div>
';
$data[$i] = array(
$obj->getName(),
($obj->getProvince()) ? $obj->getProvince()->getName() : "",
($obj->getDistrict()) ? $obj->getDistrict()->getName() : "",
($obj->getCommune()) ? $obj->getCommune()->getName() : "",
$buttons,
$obj->getId()
);
$i++;
}
}
return $data;
}
/**
* @Route("/rejestracja/data/placowki/dodana", name="PageAuthRegisterInstitutionCustomJson")
*/
public function getInstitutionCustom(): Response {
$id = $_GET["custom"];
if($id != ""){
// $data = $this->getDoctrine()->getRepository(Institution::class)->find($id);
$obj = $this->getDoctrine()->getRepository(Institution::class)->find($id);
$buttons = '
<div class="text-nowrap">
<a href="javascript:;" onclick="institutions.add(' .$obj->getId(). ')"><i class="fa fa-edit"></i></a>
<a href="javascript:;" onclick="institutions.change(' .$obj->getId(). ')"><i class="fa fa-plus-square-o"></i></a>
</div>
';
$data = array(
$obj->getName(),
($obj->getProvince()) ? $obj->getProvince()->getName() : "",
($obj->getDistrict()) ? $obj->getDistrict()->getName() : "",
($obj->getCommune()) ? $obj->getCommune()->getName() : "",
$buttons
);
return new JsonResponse( array( 'data' => $data ) , 200);
}
return new JsonResponse( array( 'data' => null ), 200);
}
/**
* @Route("/ustaw-haslo/{hash}", name="pageAuthPassword")
*/
public function password(Request $request, UserPasswordEncoderInterface $encoder, FreshMailService $freshMailService, string $hash): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('pageDashboardIndex');
}
$em = $this->getDoctrine()->getManager();
$user = $this->getDoctrine()->getRepository(User::class)->findOneBy([
'hash' => $hash
]);
if (!$user) {
return $this->redirectToRoute('pageAuthLogin');
}
$consents = $this->getDoctrine()->getRepository(Consent::class)->findBy([
'isDeleted' => false
]);
$form = $this->createForm(PageUserPasswordType::class, $user, [
'consents' => count($user->getConsentUsers()) === 0 ? $consents : [] // Jeżeli użytkownik nie ma zaznaczonych zgód, to musi je zaznaczyć (konto założone przez administratora)
]);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$isReset = false;
if ($user->getPassword()) {
$isReset = true;
}
$password = $encoder->encodePassword($user, $user->getPlainPassword());
// Zapisanie zaznaczonych zgód (jeżeli konto było zakładane przez administratora)
if (count($user->getConsentUsers()) === 0) {
$checkedConsents = $form->get("consents")->getData();
if ($checkedConsents && is_array($checkedConsents)) {
foreach ($checkedConsents as $checkedConsent) {
if ($consent = $this->getDoctrine()->getRepository(Consent::class)->find((int) $checkedConsent)) {
$consentUser = new ConsentUser;
$consentUser
->setConsenst($consent)
->setUser($user)
->setDate(new \Datetime);
$em->persist($consentUser);
if (strpos($consent->getDescription(), 'newsletter') !== false) {
$freshMailService->addSubscriber($user->getEmail());
}
}
}
}
}
// ===
$user
->setPassword($password)
->setHash(null);
$em->persist($user);
$em->flush();
if ($isReset) {
$this->addFlash('success', 'Hasło zostało zmienione.');
} else {
if ($user->getStatus() === 'ACTIVE') {
$this->addFlash('success', 'Hasło zostało ustawione. Możesz się zalogować.');
} else {
$this->addFlash('success', 'Hasło zostało ustawione. Poczekaj na akceptację Twojego konta przez administratora.');
}
}
return $this->redirectToRoute('pageAuthLogin');
}
return $this->render('page/auth/password.html.twig', [
'form' =>$form->createView(),
'user' => $user
]);
}
/**
* @Route("/resetuj-haslo", name="pageAuthResetPassword")
*/
public function resetPassword(Request $request, MailerInterface $mailer): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('pageDashboardIndex');
}
$form = $this->createForm(PageUserResetPasswordType::class);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$user = $this->getDoctrine()->getRepository(User::class)->findOneBy([
'email' => $data['email'],
'status' => 'ACTIVE'
]);
if ($user) {
$user->setHash(hash('sha256', uniqid()));
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
$link = $request->getScheme() . '://' . $request->getHttpHost() . '/ustaw-haslo/' . $user->getHash();
$message = 'Kliknij w link <a href="' . $link . '">' . $link . '</a> i ustaw nowe hasło do portalu Cała Polska Czyta Dzieciom';
$title = "Zmień hasło do portalu Cała Polska Czyta Dzieciom";
$email = (new TemplatedEmail())
->to(new Address($user->getEmail(), $user->getName() . ' ' . $user->getSurname()))
->subject($title)
->htmlTemplate('email/message.html.twig')
->context([
'title' => $title,
'message' => $message
]);
$mailer->send($email);
}
$this->addFlash('success', 'Na podany adres e-mail został wysłany link do utworzenia nowego hasła.');
return $this->redirectToRoute('pageAuthLogin');
}
return $this->render('page/auth/resetPassword.html.twig', [
'form' => $form->createView()
]);
}
/**
* @Route("/wyloguj", name="pageAuthLogout")
*/
public function logout()
{
}
/**
* @Route("/lista-placowek", name="pageAuthInstitutions")
*/
public function list(Request $request): JsonResponse
{
$name = $request->query->get('name', null);
$place = $request->query->get('place', null);
$province = (int) $request->query->get('province', 0);
$district = (int) $request->query->get('district', 0);
$commune = (int) $request->query->get('commune', 0);
$custom = (int) $request->query->get('custom', 0);
if ($custom) {
$institutionsData = $this->getDoctrine()->getRepository(Institution::class)->findBy([
'id' => $custom
]);
} else {
$institutionsData = $this->getDoctrine()->getRepository(Institution::class)->findByFilters($name, $place, $province, $district, $commune);
}
$institutions = [];
foreach ($institutionsData as $institution) {
$institutions[] = [
'id' => $institution->getId(),
'name' => $institution->getName(),
'province' => $institution->getProvince() ? $institution->getProvince()->getName() : '',
'district' => $institution->getDistrict() ? $institution->getDistrict()->getName() : '',
'commune' => $institution->getCommune() ? $institution->getCommune()->getName() : ''
];
}
return new JsonResponse($institutions);
}
/**
* @Route("/dodaj-placowke", name="pageAuthAddInstitution")
*/
public function addInstitution(Request $request, InstitutionService $institutionService): Response
{
$baseInstitution = new Institution;
if ($id = (int) $request->query->get('id')) {
$baseInstitution = $this->getDoctrine()->getRepository(Institution::class)->find($id);
}
$newInstitution = new Institution;
$newInstitution
->setName($baseInstitution->getName())
->setRegon($baseInstitution->getRegon())
->setStreet($baseInstitution->getStreet())
->setBuilding($baseInstitution->getBuilding())
->setLocalNumber($baseInstitution->getLocalNumber())
->setPostcode($baseInstitution->getPostcode())
->setPlace($baseInstitution->getPlace())
->setProvince($baseInstitution->getProvince())
->setDistrict($baseInstitution->getDistrict())
->setCommune($baseInstitution->getCommune())
->setCountry($baseInstitution->getCountry())
->setCategory($baseInstitution->getCategory())
->setType($baseInstitution->getType())
->setPhone($baseInstitution->getPhone())
->setEmail($baseInstitution->getEmail())
->setStatus('INACTIVE');
if ($baseInstitution->getId()) {
if ($baseInstitution->getTarget()) {
$newInstitution->setTarget($baseInstitution->getTarget());
} else {
$newInstitution->setTarget($baseInstitution);
}
}
$form = $this->createForm(InstitutionType::class, $newInstitution);
$form->handleRequest($request);
if(
$form->isSubmitted() &&
$form->isValid() &&
!$errors = $institutionService->validate($newInstitution)
) {
$em = $this->getDoctrine()->getManager();
$em->persist($newInstitution);
$em->flush();
}
return $this->render('page/auth/addInstitution.html.twig', [
'form' => $form->createView(),
'baseInstitution' => $baseInstitution,
'newInstitution' => $newInstitution,
'errors' => isset($errors) ? $errors : []
]);
}
/**
* @Route("/projekt/{projectUrl}", name="pageAuthProject", requirements={"projectUrl": "[a-zA-Z0-9\-]{1,}"})
*/
public function project(string $projectUrl):Response
{
$form = $this ->getDoctrine()->getRepository(Form::class)->findOneBy([
'url' => $projectUrl
]);
if(!$form){
throw $this->createNotFoundException();
}
if(!$form->getIsAssigned()){
throw $this->createNotFoundException('Nieprawidłowy formularz');
}
if($form->getType() == "evaluation"){
throw $this->createNotFoundException('Wybrano formularz ewaluacyjny');
}
$project = null;
foreach($form->getProjects() as $obj){
$project = $obj;
}
$response = $this ->redirectToRoute('pageProjectAddStep2', [
'projectId' => $project->getId()
]);
if(!$this->getUser()){
$cookie = Cookie::create('redirectToProject')
->withValue($project->getId())
->withExpires(new \DateTime('+3 days'))
->withSecure(true)
->withHttpOnly(true);
$response->headers->setCookie($cookie);
}
return $response;
}
}