diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 7b38924..1e7714e 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -35,6 +35,7 @@ security: # Note: Only the *first* access control that matches will be used access_control: - { path: ^/task/*, roles: ROLE_USER } + - { path: ^/project/*, roles: ROLE_USER } # - { path: ^/admin, roles: ROLE_ADMIN } # - { path: ^/profile, roles: ROLE_USER } diff --git a/src/Controller/ProjectController.php b/src/Controller/ProjectController.php new file mode 100644 index 0000000..cb3353d --- /dev/null +++ b/src/Controller/ProjectController.php @@ -0,0 +1,124 @@ +security = $security; + } + + /** + * @Route("/project/list", name="project_list") + */ + public function showPorjects(Request $request): Response + { + $user = $this->getUser(); + + if($this->isGranted('ROLE_ADMIN')) + { + /** @var $projects */ + $projects = $this->getDoctrine()->getManager() + ->getRepository(Project::class) + ->findBy([], []); + } + else + { + /** @var $projects */ + $projects = $this->getDoctrine()->getManager() + ->getRepository(Project::class) + ->findBy(['author' => $user->getId()]); + } + + + + return $this->render('project/index.html.twig', [ + 'projects' => $projects, + ]); + } + + /** + * @Route("/project/create", name="project_create") + */ + public function createProject(Request $request): Response + { + $project = new Project(); + $form = $this->createForm(ProjectType::class, $project); + + $form->handleRequest($request); + $user = $this->getUser(); + + + if ($form->isSubmitted() && $form->isValid()) { + + $project->setAuthor($user->getId()); + + $this->getDoctrine()->getManager()->persist($project); + $this->getDoctrine()->getManager()->flush(); + + return $this->redirectToRoute('project_list'); + } + + return $this->render('project/createForm.html.twig', [ + 'form' => $form->createView(), + ]); + } + + + /** + * @Route("/project/{id}/", name="project_byId") + */ + public function projectById($id): Response + { + /** @var Task $project */ + $project = $this->getDoctrine()->getManager()->find(Project::class, $id); + + if ($project === null) { + throw $this->createNotFoundException(sprintf("Project with id %s not found", $id)); + } + $Flag=False; + $user = $this->getUser(); + foreach ($user->getRoles() as $role) + { + if($role === 'ROLE_ADMIN') + { + $Flag=True; + } + } + + if(!$Flag) + { + if($user->getId() !== $project->getAuthor()) + { + throw $this->createAccessDeniedException(); + } + } + + $tasks = $this->getDoctrine()->getRepository(Task::class) + ->findBy(['project' => $id], []); + + return $this->render('project/project.html.twig',[ + 'id' => $id, + 'tasks' => $tasks, + ]); + } +} \ No newline at end of file diff --git a/src/Controller/TaskController.php b/src/Controller/TaskController.php index 0d9f9ad..c0549a9 100644 --- a/src/Controller/TaskController.php +++ b/src/Controller/TaskController.php @@ -2,6 +2,7 @@ namespace App\Controller; +use App\Entity\Project; use App\Entity\Task; use App\Type\TaskFilterType; use App\Type\TaskType; @@ -22,7 +23,11 @@ class TaskController extends AbstractController public function create(Request $request): Response { $task = new Task(); - $form = $this->createForm(TaskType::class, $task); + $option = [ + 'userId' => $this->getUser()->getId(), + 'userRole' => $this->getUser()->getRoles(), + ]; + $form = $this->createForm(TaskType::class, $task, $option); $form->handleRequest($request); @@ -48,6 +53,20 @@ public function create(Request $request): Response */ public function list(Request $request): Response { + $Flag=False; + $user = $this->getUser(); + foreach ($user->getRoles() as $role) + { + if($role === 'ROLE_ADMIN') + { + $Flag=True; + } + } + if(!$Flag) + { + $ids = $this->getProjectID($user->getId()); + } + $taskFilterForm = $this->createForm(TaskFilterType::class); $taskFilterForm->handleRequest($request); @@ -58,23 +77,36 @@ public function list(Request $request): Response if ($filter['isCompleted'] === null) { unset($filter['isCompleted']); } - + if(!$Flag) + { + $filter['project'] = $ids; + } $tasks = $this->getDoctrine()->getRepository(Task::class) ->findBy($filter, [ 'dueDate' => 'DESC' ]); } else { - /** @var $tasks */ - $tasks = $this->getDoctrine()->getManager() - ->getRepository(Task::class) - ->findBy([], [ - 'dueDate' => 'DESC' - ]); + if($Flag) + { + /** @var $tasks */ + $tasks = $this->getDoctrine()->getManager() + ->getRepository(Task::class) + ->findBy([], [ + 'dueDate' => 'DESC' + ]); + } + else + { + /** @var $tasks */ + $tasks = $this->getDoctrine()->getManager() + ->getRepository(Task::class) + ->findBy(['project' => $ids], [ + 'dueDate' => 'DESC' + ]); + } } - - return $this->render('task/list.html.twig', [ 'tasks' => $tasks, 'filterForm' => $taskFilterForm->createView() @@ -104,4 +136,21 @@ public function complete($id): Response return $this->redirectToRoute('task_list'); } + + private function getProjectID(int $id) + { + $returnId = []; + + /** @var $projects */ + $projects = $this->getDoctrine()->getManager() + ->getRepository(Project::class) + ->findBy(['author' => $id]); + + foreach ($projects as $project) + { + array_push($returnId, $project->getId()); + } + + return $returnId; + } } \ No newline at end of file diff --git a/src/Entity/Project.php b/src/Entity/Project.php new file mode 100644 index 0000000..bd19ac7 --- /dev/null +++ b/src/Entity/Project.php @@ -0,0 +1,75 @@ +id; + } + + public function getToken(): ?string + { + return $this->token; + } + + public function setToken(string $token): self + { + $this->token = $token; + + return $this; + } + + public function getName(): ?string + { + return $this->name; + } + + public function setName(string $name): self + { + $this->name = $name; + + return $this; + } + + public function getAuthor(): ?int + { + return $this->author; + } + + public function setAuthor(int $author): self + { + $this->author = $author; + + return $this; + } +} \ No newline at end of file diff --git a/src/Entity/Task.php b/src/Entity/Task.php index 66a4b57..3d67dc5 100644 --- a/src/Entity/Task.php +++ b/src/Entity/Task.php @@ -55,6 +55,12 @@ class Task */ protected $author; + /** + * @ORM\ManyToOne(targetEntity="App\Entity\Project", inversedBy="project") + * @var Project + */ + protected $project; + /** * Create empty task */ @@ -85,6 +91,24 @@ public function getAuthor() return $this->author; } + /** + * Set task Project + * @param Project|null $project + * @return void + */ + public function setProject(Project $project = null) + { + $this->project = $project; + } + + /** + * Return task project + * @return Project|null + */ + public function getProject() + { + return $this->project; + } /** * @return mixed diff --git a/src/Repository/ProjectRepository.php b/src/Repository/ProjectRepository.php new file mode 100644 index 0000000..89a9165 --- /dev/null +++ b/src/Repository/ProjectRepository.php @@ -0,0 +1,47 @@ +_em->persist($entity); + if ($flush) { + $this->_em->flush(); + } + } + + /** + * @throws ORMException + * @throws OptimisticLockException + */ + public function remove(Project $entity, bool $flush = true): void + { + $this->_em->remove($entity); + if ($flush) { + $this->_em->flush(); + } + } +} \ No newline at end of file diff --git a/src/Security/LoginFormAuthenticator.php b/src/Security/LoginFormAuthenticator.php index eb7b6dd..3bd0209 100644 --- a/src/Security/LoginFormAuthenticator.php +++ b/src/Security/LoginFormAuthenticator.php @@ -95,7 +95,7 @@ public function onAuthenticationSuccess(Request $request, TokenInterface $token, return new RedirectResponse($targetPath); } - return new RedirectResponse($this->urlGenerator->generate('task_list')); + return new RedirectResponse($this->urlGenerator->generate('project_list')); } protected function getLoginUrl() diff --git a/src/Type/ProjectType.php b/src/Type/ProjectType.php new file mode 100644 index 0000000..a61bf92 --- /dev/null +++ b/src/Type/ProjectType.php @@ -0,0 +1,22 @@ +add('token', TextType::class) + ->add('name', TextType::class) + ->add('save', SubmitType::class) + ; + } +} \ No newline at end of file diff --git a/src/Type/TaskType.php b/src/Type/TaskType.php index 3b58193..839a19f 100644 --- a/src/Type/TaskType.php +++ b/src/Type/TaskType.php @@ -2,24 +2,91 @@ namespace App\Type; +use App\Entity\Project; +use App\Entity\User; +use Doctrine\ORM\EntityRepository; +use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\DateType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Security\Core\User\UserInterface; class TaskType extends AbstractType { + + protected $id; + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'userId' => 0, + 'userRole' => [] + ]); + + // you can also define the allowed types, allowed values and + // any other feature supported by the OptionsResolver component + $resolver->setAllowedTypes('userId', 'int'); + $resolver->setAllowedTypes('userRole', 'array'); + } + public function buildForm(FormBuilderInterface $builder, array $options) { - $builder - ->add('name', TextType::class) - ->add('description', TextareaType::class) - ->add('dueDate', DateType::class, [ - 'years' => range(2022,2023) - ]) - ->add('save', SubmitType::class) - ; + $roles = $options['userRole']; + $flag = false; + foreach ($roles as $role) + { + if ($role === 'ROLE_ADMIN') + { + $flag = True; + } + } + + $this->id = $options['userId']; + + if ($flag) + { + $builder + ->add('name', TextType::class) + ->add('description', TextareaType::class) + ->add('dueDate', DateType::class, [ + 'years' => range(2022,2023) + ]) + ->add('project', EntityType::class, [ + 'class' => Project::class, + 'query_builder' => function (EntityRepository $er) { + $sql = sprintf('p.author = %d', $this->id); + return $er->createQueryBuilder('p') + ->orderBy('p.id', 'ASC'); + }, + 'choice_label' => 'id', + ]) + ->add('save', SubmitType::class) + ; + } + else + { + $builder + ->add('name', TextType::class) + ->add('description', TextareaType::class) + ->add('dueDate', DateType::class, [ + 'years' => range(2022,2023) + ]) + ->add('project', EntityType::class, [ + 'class' => Project::class, + 'query_builder' => function (EntityRepository $er) { + $sql = sprintf('p.author = %d', $this->id); + return $er->createQueryBuilder('p') + ->where($sql) + ->orderBy('p.id', 'ASC'); + }, + 'choice_label' => 'id', + ]) + ->add('save', SubmitType::class) + ; + } } } \ No newline at end of file diff --git a/templates/project/createForm.html.twig b/templates/project/createForm.html.twig new file mode 100644 index 0000000..fa54bb7 --- /dev/null +++ b/templates/project/createForm.html.twig @@ -0,0 +1,16 @@ +{% extends 'base.html.twig' %} + +{% block body %} + +
+
+
+
+
+ {{ form(form, {'action': path('project_create'), 'method': 'POST'}) }} +
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/project/index.html.twig b/templates/project/index.html.twig new file mode 100644 index 0000000..21c486c --- /dev/null +++ b/templates/project/index.html.twig @@ -0,0 +1,35 @@ +{% extends 'base.html.twig' %} + +{% block body %} +
+
+
+
+
+ {# {{ form(filterForm, {"action" : path('task_list'), "method" : "GET"}) }}#} + + + + + + + + + + {% for project in projects %} + + < + + + + {% endfor %} + +
#TokenName
{{ project.id }}{{ project.token }}{{ project.name }}
+ + Создать задачу +
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/project/project.html.twig b/templates/project/project.html.twig new file mode 100644 index 0000000..98291aa --- /dev/null +++ b/templates/project/project.html.twig @@ -0,0 +1,46 @@ +{% extends 'base.html.twig' %} + +{% block body %} + +
+
+
+
+
+ + + + + + + + + + + + + + + {% for task in tasks %} + + + + + + + + + + {% endfor %} + +
#НазваниеОписаниеСрок выполненияАвторВыполненаДействия
{{ task.id }}{{ task.name }}{{ task.description }}{{ task.dueDate|date("d.m.Y") }}{{ task.author }}{{ task.isCompleted ? 'Выполнена' : 'Не выполнена' }} + {% if (is_granted("complete", task)) %} + Сделано + {% endif %} +
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/security/login.html.twig b/templates/security/login.html.twig index 7490fa3..db7d331 100644 --- a/templates/security/login.html.twig +++ b/templates/security/login.html.twig @@ -16,7 +16,7 @@

Please sign in

- + diff --git a/templates/task/list.html.twig b/templates/task/list.html.twig index 0d50fd4..2759f1b 100644 --- a/templates/task/list.html.twig +++ b/templates/task/list.html.twig @@ -38,7 +38,7 @@ - Создать задачу + Создать задачу