From c24426845a77f87958da898e98570df32c2daf1c Mon Sep 17 00:00:00 2001 From: Danil Bashkov Date: Sat, 21 May 2022 12:37:53 +0500 Subject: [PATCH 1/2] Add some field --- .env | 2 +- migrations/Version20220521063424.php | 33 ++++++++++++ migrations/Version20220521070901.php | 35 +++++++++++++ src/Controller/ProjectController.php | 53 +++++++++++++++++++ src/Entity/Project.php | 76 ++++++++++++++++++++++++++++ src/Entity/User.php | 42 +++++++++++++++ src/Form/ProjectType.php | 22 ++++++++ src/Repository/ProjectRepository.php | 76 ++++++++++++++++++++++++++++ templates/project/create.html.twig | 16 ++++++ templates/project/list.html.twig | 38 ++++++++++++++ 10 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 migrations/Version20220521063424.php create mode 100644 migrations/Version20220521070901.php create mode 100644 src/Controller/ProjectController.php create mode 100644 src/Entity/Project.php create mode 100644 src/Form/ProjectType.php create mode 100644 src/Repository/ProjectRepository.php create mode 100644 templates/project/create.html.twig create mode 100644 templates/project/list.html.twig diff --git a/.env b/.env index 11831a1..042d484 100644 --- a/.env +++ b/.env @@ -29,6 +29,6 @@ APP_SECRET=b2b0f5c49ef6e56406e93246d9250c00 # IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml # # DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db" -DATABASE_URL="mysql://symfony:symfony@localhost:3306/symfony?serverVersion=10.3.34-MariaDB&charset=utf8mb4" +DATABASE_URL="mysql://symfony:symfony@127.0.0.1:3306/symfony?serverVersion=10.3.34-MariaDB&charset=utf8mb4" # DATABASE_URL="postgresql://db_user:db_password@127.0.0.1:5432/db_name?ser/verVersion=13&charset=utf8" ###< doctrine/doctrine-bundle ### diff --git a/migrations/Version20220521063424.php b/migrations/Version20220521063424.php new file mode 100644 index 0000000..709e6b6 --- /dev/null +++ b/migrations/Version20220521063424.php @@ -0,0 +1,33 @@ +addSql('CREATE TABLE project (id INT AUTO_INCREMENT NOT NULL, key_project VARCHAR(5) NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('ALTER TABLE task CHANGE is_completed is_completed TINYINT(1) DEFAULT 0 NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('DROP TABLE project'); + $this->addSql('ALTER TABLE task CHANGE is_completed is_completed TINYINT(1) DEFAULT NULL'); + } +} diff --git a/migrations/Version20220521070901.php b/migrations/Version20220521070901.php new file mode 100644 index 0000000..9753b53 --- /dev/null +++ b/migrations/Version20220521070901.php @@ -0,0 +1,35 @@ +addSql('ALTER TABLE project ADD author_id INT NOT NULL, CHANGE name name VARCHAR(255) NOT NULL'); + $this->addSql('ALTER TABLE project ADD CONSTRAINT FK_2FB3D0EEF675F31B FOREIGN KEY (author_id) REFERENCES user (id)'); + $this->addSql('CREATE INDEX IDX_2FB3D0EEF675F31B ON project (author_id)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE project DROP FOREIGN KEY FK_2FB3D0EEF675F31B'); + $this->addSql('DROP INDEX IDX_2FB3D0EEF675F31B ON project'); + $this->addSql('ALTER TABLE project DROP author_id, CHANGE name name VARCHAR(255) DEFAULT NULL'); + } +} diff --git a/src/Controller/ProjectController.php b/src/Controller/ProjectController.php new file mode 100644 index 0000000..e1ae995 --- /dev/null +++ b/src/Controller/ProjectController.php @@ -0,0 +1,53 @@ +getDoctrine()->getManager() + ->getRepository(Project::class)->findBy([]); + return $this->render('project/list.html.twig', [ + 'projects' => $projects, + ]); + } + + + /** + * @Route("/projects/create", name="project_create") + */ + public function create(Request $request): Response + { + $project = new Project(); + $form = $this->createForm(ProjectType::class, $project); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + + $project->setAuthor($this->getUser()); + + $this->getDoctrine()->getManager()->persist($project); + $this->getDoctrine()->getManager()->flush(); + + return $this->redirectToRoute('project_list'); + } + + return $this->render("project/create.html.twig", [ + 'form' => $form->createView() + ]); + + } +} diff --git a/src/Entity/Project.php b/src/Entity/Project.php new file mode 100644 index 0000000..892d84c --- /dev/null +++ b/src/Entity/Project.php @@ -0,0 +1,76 @@ +id; + } + + public function getKeyProject(): ?string + { + return $this->keyProject; + } + + public function setKeyProject(string $keyProject): self + { + $this->keyProject = $keyProject; + + return $this; + } + + public function getName(): ?string + { + return $this->name; + } + + public function setName(?string $name): self + { + $this->name = $name; + + return $this; + } + + public function getAuthor(): ?User + { + return $this->author; + } + + public function setAuthor(?User $author): self + { + $this->author = $author; + + return $this; + } +} diff --git a/src/Entity/User.php b/src/Entity/User.php index 98648d0..5647027 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -3,6 +3,8 @@ namespace App\Entity; use App\Repository\UserRepository; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\UserInterface; @@ -34,6 +36,16 @@ class User implements UserInterface */ private $password; + /** + * @ORM\OneToMany(targetEntity=Project::class, mappedBy="author") + */ + private $projects; + + public function __construct() + { + $this->projects = new ArrayCollection(); + } + public function __toString() { return $this->getUsername(); @@ -120,4 +132,34 @@ public function eraseCredentials() // If you store any temporary, sensitive data on the user, clear it here // $this->plainPassword = null; } + + /** + * @return Collection + */ + public function getProjects(): Collection + { + return $this->projects; + } + + public function addProject(Project $project): self + { + if (!$this->projects->contains($project)) { + $this->projects[] = $project; + $project->setAuthor($this); + } + + return $this; + } + + public function removeProject(Project $project): self + { + if ($this->projects->removeElement($project)) { + // set the owning side to null (unless already changed) + if ($project->getAuthor() === $this) { + $project->setAuthor(null); + } + } + + return $this; + } } diff --git a/src/Form/ProjectType.php b/src/Form/ProjectType.php new file mode 100644 index 0000000..38b9536 --- /dev/null +++ b/src/Form/ProjectType.php @@ -0,0 +1,22 @@ +add('keyProject', TextType::class) + ->add('name', TextType::class) + ->add('save', SubmitType::class) + ; + } +} diff --git a/src/Repository/ProjectRepository.php b/src/Repository/ProjectRepository.php new file mode 100644 index 0000000..560cb87 --- /dev/null +++ b/src/Repository/ProjectRepository.php @@ -0,0 +1,76 @@ +_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(); + } + } + + // /** + // * @return Project[] Returns an array of Project objects + // */ + /* + public function findByExampleField($value) + { + return $this->createQueryBuilder('p') + ->andWhere('p.exampleField = :val') + ->setParameter('val', $value) + ->orderBy('p.id', 'ASC') + ->setMaxResults(10) + ->getQuery() + ->getResult() + ; + } + */ + + /* + public function findOneBySomeField($value): ?Project + { + return $this->createQueryBuilder('p') + ->andWhere('p.exampleField = :val') + ->setParameter('val', $value) + ->getQuery() + ->getOneOrNullResult() + ; + } + */ +} diff --git a/templates/project/create.html.twig b/templates/project/create.html.twig new file mode 100644 index 0000000..d8d1a08 --- /dev/null +++ b/templates/project/create.html.twig @@ -0,0 +1,16 @@ +{% extends 'base.html.twig' %} + +{% block body %} + +
+
+
+
+
+ {{ form(form, {'action': path('project_create'), 'method': 'POST'}) }} +
+
+
+
+
+{% endblock %} diff --git a/templates/project/list.html.twig b/templates/project/list.html.twig new file mode 100644 index 0000000..6ae48cd --- /dev/null +++ b/templates/project/list.html.twig @@ -0,0 +1,38 @@ +{% extends 'base.html.twig' %} + +{% block body %} +
+
+
+
+
+ + + + + + + + + + + + {% for project in projects %} + + + + + + + {% endfor %} + +
#idНазваниеАвторДействия
{{ project.id }}{{ project.keyProject }}{{ project.name }}{{ project.author }}
+ + Make project + +
+
+
+
+
+{% endblock %} From c77a53e8527b6937b50ea324242511e351ca25da Mon Sep 17 00:00:00 2001 From: bda-nt <74663073+bda-nt@users.noreply.github.com> Date: Thu, 2 Jun 2022 18:51:56 +0500 Subject: [PATCH 2/2] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=207=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=B4=D0=B0=D1=87=20(1-7).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/packages/security.yaml | 2 +- config/routes.yaml | 6 +-- migrations/Version20220521070901.php | 35 --------------- ...21063424.php => Version20220602121009.php} | 5 ++- migrations/Version20220602123943.php | 35 +++++++++++++++ src/Controller/ProjectController.php | 31 ++++++++++++- src/Entity/Task.php | 15 ++++++- src/Entity/User.php | 30 ------------- src/Repository/ProjectRepository.php | 11 +++++ src/Type/TaskType.php | 7 +++ templates/project/list.html.twig | 5 ++- templates/project/show.html.twig | 45 +++++++++++++++++++ templates/task/list.html.twig | 6 ++- 13 files changed, 155 insertions(+), 78 deletions(-) delete mode 100644 migrations/Version20220521070901.php rename migrations/{Version20220521063424.php => Version20220602121009.php} (70%) create mode 100644 migrations/Version20220602123943.php create mode 100644 templates/project/show.html.twig diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 7b38924..787631a 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -35,6 +35,6 @@ 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/config/routes.yaml b/config/routes.yaml index c3283aa..fee3c65 100644 --- a/config/routes.yaml +++ b/config/routes.yaml @@ -1,3 +1,3 @@ -#index: -# path: / -# controller: App\Controller\DefaultController::index +index: + path: / + controller: App\Controller\ProjectController::list diff --git a/migrations/Version20220521070901.php b/migrations/Version20220521070901.php deleted file mode 100644 index 9753b53..0000000 --- a/migrations/Version20220521070901.php +++ /dev/null @@ -1,35 +0,0 @@ -addSql('ALTER TABLE project ADD author_id INT NOT NULL, CHANGE name name VARCHAR(255) NOT NULL'); - $this->addSql('ALTER TABLE project ADD CONSTRAINT FK_2FB3D0EEF675F31B FOREIGN KEY (author_id) REFERENCES user (id)'); - $this->addSql('CREATE INDEX IDX_2FB3D0EEF675F31B ON project (author_id)'); - } - - public function down(Schema $schema): void - { - // this down() migration is auto-generated, please modify it to your needs - $this->addSql('ALTER TABLE project DROP FOREIGN KEY FK_2FB3D0EEF675F31B'); - $this->addSql('DROP INDEX IDX_2FB3D0EEF675F31B ON project'); - $this->addSql('ALTER TABLE project DROP author_id, CHANGE name name VARCHAR(255) DEFAULT NULL'); - } -} diff --git a/migrations/Version20220521063424.php b/migrations/Version20220602121009.php similarity index 70% rename from migrations/Version20220521063424.php rename to migrations/Version20220602121009.php index 709e6b6..ff9270c 100644 --- a/migrations/Version20220521063424.php +++ b/migrations/Version20220602121009.php @@ -10,7 +10,7 @@ /** * Auto-generated Migration: Please modify to your needs! */ -final class Version20220521063424 extends AbstractMigration +final class Version20220602121009 extends AbstractMigration { public function getDescription(): string { @@ -20,7 +20,8 @@ public function getDescription(): string public function up(Schema $schema): void { // this up() migration is auto-generated, please modify it to your needs - $this->addSql('CREATE TABLE project (id INT AUTO_INCREMENT NOT NULL, key_project VARCHAR(5) NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('CREATE TABLE project (id INT AUTO_INCREMENT NOT NULL, author_id INT NOT NULL, key_project VARCHAR(5) NOT NULL, name VARCHAR(255) NOT NULL, INDEX IDX_2FB3D0EEF675F31B (author_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('ALTER TABLE project ADD CONSTRAINT FK_2FB3D0EEF675F31B FOREIGN KEY (author_id) REFERENCES user (id)'); $this->addSql('ALTER TABLE task CHANGE is_completed is_completed TINYINT(1) DEFAULT 0 NOT NULL'); } diff --git a/migrations/Version20220602123943.php b/migrations/Version20220602123943.php new file mode 100644 index 0000000..6def082 --- /dev/null +++ b/migrations/Version20220602123943.php @@ -0,0 +1,35 @@ +addSql('ALTER TABLE task ADD project_id INT NOT NULL'); + $this->addSql('ALTER TABLE task ADD CONSTRAINT FK_527EDB25166D1F9C FOREIGN KEY (project_id) REFERENCES project (id)'); + $this->addSql('CREATE INDEX IDX_527EDB25166D1F9C ON task (project_id)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE task DROP FOREIGN KEY FK_527EDB25166D1F9C'); + $this->addSql('DROP INDEX IDX_527EDB25166D1F9C ON task'); + $this->addSql('ALTER TABLE task DROP project_id'); + } +} diff --git a/src/Controller/ProjectController.php b/src/Controller/ProjectController.php index e1ae995..7f8283b 100644 --- a/src/Controller/ProjectController.php +++ b/src/Controller/ProjectController.php @@ -3,13 +3,17 @@ namespace App\Controller; use App\Entity\Project; +use App\Entity\Task; use App\Form\ProjectType; -use App\Repository\ProjectRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use App\Type\TaskFilterType; +use App\Type\TaskType; +use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted; use Symfony\Component\Routing\Annotation\Route; + class ProjectController extends AbstractController { /** @@ -17,8 +21,10 @@ class ProjectController extends AbstractController */ public function list(): Response { + $user = $this->getUser(); $projects = $this->getDoctrine()->getManager() - ->getRepository(Project::class)->findBy([]); + ->getRepository(Project::class) + ->getAvailableProjects($user->getId(), $this->isGranted('ROLE_ADMIN')); return $this->render('project/list.html.twig', [ 'projects' => $projects, ]); @@ -48,6 +54,27 @@ public function create(Request $request): Response return $this->render("project/create.html.twig", [ 'form' => $form->createView() ]); + } + + /** + * @Route("project/show={id}", name="show_porject") + * @param $id + * @return void + */ + public function show($id): Response + { + $project = $this->getDoctrine()->getManager()->find(Project::class, $id); + + if ($project === null) { + throw $this->createNotFoundException(sprintf("Project with id %s not found", $id)); + } + $tasks = $this->getDoctrine()->getRepository(Task::class) + ->findBy(['project' => $id], []); + + return $this->render('project/show.html.twig',[ + 'id' => $id, + 'tasks' => $tasks, + ]); } } diff --git a/src/Entity/Task.php b/src/Entity/Task.php index 66a4b57..f7dd285 100644 --- a/src/Entity/Task.php +++ b/src/Entity/Task.php @@ -55,6 +55,11 @@ class Task */ protected $author; + /** + * @ORM\ManyToOne(targetEntity=Project::class, inversedBy="project") + */ + private $project; + /** * Create empty task */ @@ -161,7 +166,15 @@ public function setIsCompleted(bool $isCompleted = false) $this->isCompleted = $isCompleted; } + public function getProject(): ?Project + { + return $this->project; + } + public function setProject(?Project $project): self + { + $this->project = $project; - + return $this; + } } \ No newline at end of file diff --git a/src/Entity/User.php b/src/Entity/User.php index 5647027..1e321f4 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -132,34 +132,4 @@ public function eraseCredentials() // If you store any temporary, sensitive data on the user, clear it here // $this->plainPassword = null; } - - /** - * @return Collection - */ - public function getProjects(): Collection - { - return $this->projects; - } - - public function addProject(Project $project): self - { - if (!$this->projects->contains($project)) { - $this->projects[] = $project; - $project->setAuthor($this); - } - - return $this; - } - - public function removeProject(Project $project): self - { - if ($this->projects->removeElement($project)) { - // set the owning side to null (unless already changed) - if ($project->getAuthor() === $this) { - $project->setAuthor(null); - } - } - - return $this; - } } diff --git a/src/Repository/ProjectRepository.php b/src/Repository/ProjectRepository.php index 560cb87..efbb0a6 100644 --- a/src/Repository/ProjectRepository.php +++ b/src/Repository/ProjectRepository.php @@ -7,6 +7,7 @@ use Doctrine\ORM\OptimisticLockException; use Doctrine\ORM\ORMException; use Doctrine\Persistence\ManagerRegistry; +use phpDocumentor\Reflection\Types\This; /** * @method Project|null find($id, $lockMode = null, $lockVersion = null) @@ -21,6 +22,16 @@ public function __construct(ManagerRegistry $registry) parent::__construct($registry, Project::class); } + public function getAvailableProjects(int $id, bool $hasAdmin = false) { + if ($hasAdmin) { + return $this->getEntityManager()->getRepository(Project::class) + ->findAll(); + } + $filter['author'] = $id; + + return $this->getEntityManager()->getRepository(Project::class)->findBy($filter); + } + /** * @throws ORMException * @throws OptimisticLockException diff --git a/src/Type/TaskType.php b/src/Type/TaskType.php index 3b58193..488602a 100644 --- a/src/Type/TaskType.php +++ b/src/Type/TaskType.php @@ -2,7 +2,10 @@ namespace App\Type; +use App\Entity\Project; +use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\DateType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; @@ -19,6 +22,10 @@ public function buildForm(FormBuilderInterface $builder, array $options) ->add('dueDate', DateType::class, [ 'years' => range(2022,2023) ]) + ->add('Project', EntityType::class, [ + 'class' => Project::class, + 'choice_label' => 'name', + ]) ->add('save', SubmitType::class) ; } diff --git a/templates/project/list.html.twig b/templates/project/list.html.twig index 6ae48cd..d4a920f 100644 --- a/templates/project/list.html.twig +++ b/templates/project/list.html.twig @@ -19,7 +19,7 @@ {% for project in projects %} - {{ project.id }} + {{ project.id }} {{ project.keyProject }} {{ project.name }} {{ project.author }} @@ -28,7 +28,8 @@ - Make project + Make project
+ Go to task list
diff --git a/templates/project/show.html.twig b/templates/project/show.html.twig new file mode 100644 index 0000000..3ce8be4 --- /dev/null +++ b/templates/project/show.html.twig @@ -0,0 +1,45 @@ +{% 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/task/list.html.twig b/templates/task/list.html.twig index 0d50fd4..91ae845 100644 --- a/templates/task/list.html.twig +++ b/templates/task/list.html.twig @@ -15,6 +15,7 @@ Описание Срок выполнения Автор + Проект Выполнена Действия @@ -27,6 +28,7 @@ {{ task.description }} {{ task.dueDate|date("d.m.Y") }} {{ task.author }} + {{ task.project.name }} {{ task.isCompleted ? 'Выполнена' : 'Не выполнена' }} {% if (is_granted("complete", task)) %} @@ -38,8 +40,8 @@ - Создать задачу - + Создать задачу
+ Go to project list