From 3f2a19335f237e2b2b6d0d6dd437ad1a90d6689e Mon Sep 17 00:00:00 2001 From: "kaushik.prajapati" Date: Wed, 3 Oct 2018 16:45:32 +0530 Subject: [PATCH] WikiBundle phase 1 --- Controller/WikiController.php | 117 ++++++++++++++++ Controller/WikiEventController.php | 30 +++++ Controller/WikiPageController.php | 132 +++++++++++++++++++ DependencyInjection/LinkorbWikiExtension.php | 21 +++ Entity/Wiki.php | 100 ++++++++++++++ Entity/WikiEvent.php | 125 ++++++++++++++++++ Entity/WikiPage.php | 92 +++++++++++++ Form/WikiPageType.php | 70 ++++++++++ Form/WikiType.php | 63 +++++++++ LinkorbWikiBundle.php | 9 ++ README.md | 1 + Repository/WikiEventRepository.php | 26 ++++ Repository/WikiPageRepository.php | 60 +++++++++ Repository/WikiRepository.php | 26 ++++ Resources/Services/WikiEventService.php | 42 ++++++ Resources/config/routing.yaml | 0 Resources/config/services.xml | 13 ++ Resources/config/services.yaml | 8 ++ Resources/views/wiki/edit.html.twig | 21 +++ Resources/views/wiki/index.html.twig | 60 +++++++++ Resources/views/wiki_event/index.html.twig | 50 +++++++ Resources/views/wiki_page/edit.html.twig | 42 ++++++ Resources/views/wiki_page/index.html.twig | 50 +++++++ Resources/views/wiki_page/view.html.twig | 38 ++++++ composer.json | 20 +++ 25 files changed, 1216 insertions(+) create mode 100644 Controller/WikiController.php create mode 100644 Controller/WikiEventController.php create mode 100644 Controller/WikiPageController.php create mode 100644 DependencyInjection/LinkorbWikiExtension.php create mode 100644 Entity/Wiki.php create mode 100644 Entity/WikiEvent.php create mode 100644 Entity/WikiPage.php create mode 100644 Form/WikiPageType.php create mode 100644 Form/WikiType.php create mode 100644 LinkorbWikiBundle.php create mode 100644 README.md create mode 100644 Repository/WikiEventRepository.php create mode 100644 Repository/WikiPageRepository.php create mode 100644 Repository/WikiRepository.php create mode 100644 Resources/Services/WikiEventService.php create mode 100644 Resources/config/routing.yaml create mode 100644 Resources/config/services.xml create mode 100755 Resources/config/services.yaml create mode 100644 Resources/views/wiki/edit.html.twig create mode 100644 Resources/views/wiki/index.html.twig create mode 100644 Resources/views/wiki_event/index.html.twig create mode 100644 Resources/views/wiki_page/edit.html.twig create mode 100644 Resources/views/wiki_page/index.html.twig create mode 100644 Resources/views/wiki_page/view.html.twig create mode 100644 composer.json diff --git a/Controller/WikiController.php b/Controller/WikiController.php new file mode 100644 index 0000000..9f3a1f6 --- /dev/null +++ b/Controller/WikiController.php @@ -0,0 +1,117 @@ +render('@wiki_bundle/wiki/index.html.twig', ['wikis' => $wikiRepository->findAll()]); + } + + /** + * @Route("/add", name="wiki_add", methods="GET|POST") + */ + public function AddAction(Request $request, WikiEventService $wikiEventService): Response + { + $wiki = new Wiki(); + + return $this->getEditForm($request, $wiki, $wikiEventService); + } + + /** + * @Route("/{wikiName}/edit", name="wiki_edit", methods="GET|POST") + * @ParamConverter("wiki", options={"mapping"={"wikiName"="name"}}) + */ + public function editAction(Request $request, Wiki $wiki, WikiEventService $wikiEventService): Response + { + return $this->getEditForm($request, $wiki, $wikiEventService); + } + + /** + * @Route("/{wikiName}/delete", name="wiki_delete", methods="GET") + * @ParamConverter("wiki", options={"mapping"={"wikiName"="name"}}) + */ + public function deleteAction(Request $request, Wiki $wiki, WikiEventService $wikiEventService): Response + { + if (count($wiki->getWikiPages())) { + $this->addFlash('error', 'The wiki cannot be deleted because of having a wiki-page.'); + } else { + $wikiEventService->createEvent( + 'wiki.deleted', + $wiki->getId(), + json_encode([ + 'deletedAt' => time(), + 'deletedBy' => $this->getUser()->getUsername(), + 'name' => $wiki->getName(), + ]) + ); + $em = $this->getDoctrine()->getManager(); + $em->remove($wiki); + $em->flush(); + } + + return $this->redirectToRoute('wiki_index'); + } + + protected function getEditForm(Request $request, Wiki $wiki, WikiEventService $wikiEventService) + { + $form = $this->createForm(WikiType::class, $wiki); + $form->handleRequest($request); + + $add = !$wiki->getid(); + + if ($form->isSubmitted() && $form->isValid()) { + $em = $this->getDoctrine()->getManager(); + $em->persist($wiki); + $em->flush(); + + if ($add) { + $wikiEventService->createEvent( + 'wiki.created', + $wiki->getId(), + json_encode([ + 'createdAt' => time(), + 'createdBy' => $this->getUser()->getUsername(), + 'name' => $wiki->getName(), + 'description' => $wiki->getDescription(), + ]) + ); + } else { + $wikiEventService->createEvent( + 'wiki.updated', + $wiki->getId(), + json_encode([ + 'updatedAt' => time(), + 'updatedBy' => $this->getUser()->getUsername(), + 'name' => $wiki->getName(), + 'description' => $wiki->getDescription(), + ]) + ); + } + + return $this->redirectToRoute('wiki_index'); + } + + return $this->render('@wiki_bundle/wiki/edit.html.twig', [ + 'wiki' => $wiki, + 'form' => $form->createView(), + ]); + } +} diff --git a/Controller/WikiEventController.php b/Controller/WikiEventController.php new file mode 100644 index 0000000..b8b2566 --- /dev/null +++ b/Controller/WikiEventController.php @@ -0,0 +1,30 @@ +findOneByName($wikiName)) { + return $this->redirectToRoute('wiki_index'); + } + $wikiEvents = $wikiEventRepository->findByWikiId($wiki->getId()); + + return $this->render('@wiki_bundle/wiki_event/index.html.twig', [ + 'wikiEvents' => $wikiEvents, + 'wiki' => $wiki, + ]); + } +} diff --git a/Controller/WikiPageController.php b/Controller/WikiPageController.php new file mode 100644 index 0000000..62b9286 --- /dev/null +++ b/Controller/WikiPageController.php @@ -0,0 +1,132 @@ +render('@wiki_bundle/wiki_page/index.html.twig', [ + 'wikiPages' => $wikiPageRepository->findByWikiId($wiki->getId()), + 'wiki' => $wiki, + ]); + } + + /** + * @Route("/pages/add", name="wiki_page_add", methods="GET|POST") + */ + public function addAction(Request $request, Wiki $wiki, WikiEventService $wikiEventService): Response + { + $wikiPage = new WikiPage(); + $wikiPage->setWiki($wiki); + + return $this->getEditForm($request, $wikiPage, $wikiEventService); + } + + /** + * @Route("/{pageName}", name="wiki_page_view", methods="GET") + * @ParamConverter("wikiPage", options={"mapping"={"pageName"="name"}}) + */ + public function viewAction(WikiPage $wikiPage): Response + { + return $this->render('@wiki_bundle/wiki_page/view.html.twig', ['wikiPage' => $wikiPage]); + } + + /** + * @Route("/pages/{id}/edit", name="wiki_page_edit", methods="GET|POST") + */ + public function editAction(Request $request, Wiki $wiki, WikiPage $wikiPage, WikiEventService $wikiEventService): Response + { + return $this->getEditForm($request, $wikiPage, $wikiEventService); + } + + /** + * @Route("/pages/{id}/delete", name="wiki_page_delete", methods="GET") + */ + public function deleteAction(Request $request, Wiki $wiki, WikiPage $wikiPage, WikiEventService $wikiEventService): Response + { + $wikiEventService->createEvent( + 'page.deleted', + $wikiPage->getWiki()->getId(), + json_encode([ + 'deletedAt' => time(), + 'deletedBy' => $this->getUser()->getUsername(), + 'name' => $wikiPage->getName(), + ]), + $wikiPage->getId() + ); + + $em = $this->getDoctrine()->getManager(); + $em->remove($wikiPage); + $em->flush(); + + return $this->redirectToRoute('wiki_page_index', [ + 'wikiName' => $wiki->getName(), + ]); + } + + protected function getEditForm($request, $wikiPage, WikiEventService $wikiEventService) + { + $form = $this->createForm(WikiPageType::class, $wikiPage); + $form->handleRequest($request); + + $add = !$wikiPage->getId(); + + if ($form->isSubmitted() && $form->isValid()) { + $em = $this->getDoctrine()->getManager(); + $em->persist($wikiPage); + $em->flush(); + + if ($add) { + $wikiEventService->createEvent( + 'page.created', + $wikiPage->getWiki()->getId(), + json_encode([ + 'createdAt' => time(), + 'createdBy' => $this->getUser()->getUsername(), + 'name' => $wikiPage->getName(), + ]), + $wikiPage->getId() + ); + } else { + $wikiEventService->createEvent( + 'page.updated', + $wikiPage->getWiki()->getId(), + json_encode([ + 'updatedAt' => time(), + 'updatedBy' => $this->getUser()->getUsername(), + 'name' => $wikiPage->getName(), + ]), + $wikiPage->getId() + ); + } + + return $this->redirectToRoute('wiki_page_index', [ + 'wikiName' => $wikiPage->getWiki()->getName(), + ]); + } + + return $this->render('@wiki_bundle/wiki_page/edit.html.twig', [ + 'wikiPage' => $wikiPage, + 'form' => $form->createView(), + ]); + } +} diff --git a/DependencyInjection/LinkorbWikiExtension.php b/DependencyInjection/LinkorbWikiExtension.php new file mode 100644 index 0000000..c7cf6e4 --- /dev/null +++ b/DependencyInjection/LinkorbWikiExtension.php @@ -0,0 +1,21 @@ +load('services.xml'); + + $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.yaml'); + } +} diff --git a/Entity/Wiki.php b/Entity/Wiki.php new file mode 100644 index 0000000..7c068cc --- /dev/null +++ b/Entity/Wiki.php @@ -0,0 +1,100 @@ +wikiPages = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function getName(): ?string + { + return $this->name; + } + + public function setName(string $name): self + { + $this->name = $name; + + return $this; + } + + public function getDescription(): ?string + { + return $this->description; + } + + public function setDescription(string $description): self + { + $this->description = $description; + + return $this; + } + + /** + * @return Collection|WikiPage[] + */ + public function getWikiPages(): Collection + { + return $this->wikiPages; + } + + public function addWikiPage(WikiPage $wikiPage): self + { + if (!$this->wikiPages->contains($wikiPage)) { + $this->wikiPages[] = $wikiPage; + $wikiPage->setWiki($this); + } + + return $this; + } + + public function removeWikiPage(WikiPage $wikiPage): self + { + if ($this->wikiPages->contains($wikiPage)) { + $this->wikiPages->removeElement($wikiPage); + // set the owning side to null (unless already changed) + if ($wikiPage->getWiki() === $this) { + $wikiPage->setWiki(null); + } + } + + return $this; + } +} diff --git a/Entity/WikiEvent.php b/Entity/WikiEvent.php new file mode 100644 index 0000000..c6ced8a --- /dev/null +++ b/Entity/WikiEvent.php @@ -0,0 +1,125 @@ +id; + } + + public function getType(): ?string + { + return $this->type; + } + + public function setType(string $type): self + { + $this->type = $type; + + return $this; + } + + public function getCreatedAt(): ?int + { + return $this->created_at; + } + + public function setCreatedAt(int $created_at): self + { + $this->created_at = $created_at; + + return $this; + } + + public function getCreatedBy(): ?string + { + return $this->created_by; + } + + public function setCreatedBy(string $created_by): self + { + $this->created_by = $created_by; + + return $this; + } + + public function getWikiPageId(): ?int + { + return $this->wiki_page_id; + } + + public function setWikiPageId(?int $wiki_page_id): self + { + $this->wiki_page_id = $wiki_page_id; + + return $this; + } + + public function getData(): ?string + { + return $this->data; + } + + public function setData(?string $data): self + { + $this->data = $data; + + return $this; + } + + public function getWikiId(): ?int + { + return $this->wiki_id; + } + + public function setWikiId(?int $wiki_id): self + { + $this->wiki_id = $wiki_id; + + return $this; + } +} diff --git a/Entity/WikiPage.php b/Entity/WikiPage.php new file mode 100644 index 0000000..88fb2f6 --- /dev/null +++ b/Entity/WikiPage.php @@ -0,0 +1,92 @@ +id; + } + + public function getWiki(): ?Wiki + { + return $this->wiki; + } + + public function setWiki(?Wiki $wiki): self + { + $this->wiki = $wiki; + + return $this; + } + + public function getName(): ?string + { + return $this->name; + } + + public function setName(string $name): self + { + $this->name = $name; + + return $this; + } + + public function getContent(): ?string + { + return $this->content; + } + + public function setContent(?string $content): self + { + $this->content = $content; + + return $this; + } + + public function getData(): ?string + { + return $this->data; + } + + public function setData(?string $data): self + { + $this->data = $data; + + return $this; + } +} diff --git a/Form/WikiPageType.php b/Form/WikiPageType.php new file mode 100644 index 0000000..77bb6d5 --- /dev/null +++ b/Form/WikiPageType.php @@ -0,0 +1,70 @@ +wikiPageRepository = $wikiPageRepository; + } + + public function buildForm(FormBuilderInterface $builder, array $options) + { + $wikiPageRepository = $this->wikiPageRepository; + $entity = $options['data']; + + $builder + ->add('name', TextType::class, [ + 'required' => true, + 'trim' => true, + 'constraints' => [ + new Assert\NotBlank(), + new CodeConstraint(), + new Assert\Callback( + function ($name, ExecutionContext $context) use ($wikiPageRepository, $entity) { + if ($findEntity = $wikiPageRepository->findOneByWikiIdAndName($entity->getWiki()->getId(), $name)) { + if ($findEntity->getId() != $entity->getId()) { + $context->addViolation('Name already exist'); + } + } + } + ), + ], + ]) + ->add('content', TextareaType::class, [ + 'required' => false, + 'trim' => true, + ]) + ->add('data', TextareaType::class, [ + 'required' => false, + 'trim' => true, + 'attr' => [ + 'class' => 'ace-editor', + 'data-mode' => 'yaml', + 'data-lines' => '10', + ], + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => WikiPage::class, + ]); + } +} diff --git a/Form/WikiType.php b/Form/WikiType.php new file mode 100644 index 0000000..c84e9fb --- /dev/null +++ b/Form/WikiType.php @@ -0,0 +1,63 @@ +wikiRepository = $wikiRepository; + } + + public function buildForm(FormBuilderInterface $builder, array $options) + { + $wikiRepository = $this->wikiRepository; + $entity = $options['data']; + + $builder + ->add('name', TextType::class, [ + 'required' => true, + 'trim' => true, + 'constraints' => [ + new Assert\NotBlank(), + new CodeConstraint(), + new Assert\Callback( + function ($name, ExecutionContext $context) use ($wikiRepository, $entity) { + if ($findEntity = $wikiRepository->findOneByName($name)) { + if ($findEntity->getId() != $entity->getId()) { + $context->addViolation('Name already exist'); + } + } + } + ), + ], + ]) + ->add('description', TextType::class, [ + 'required' => true, + 'trim' => true, + 'constraints' => [ + new Assert\NotBlank(), + ], + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => Wiki::class, + ]); + } +} diff --git a/LinkorbWikiBundle.php b/LinkorbWikiBundle.php new file mode 100644 index 0000000..ed73bda --- /dev/null +++ b/LinkorbWikiBundle.php @@ -0,0 +1,9 @@ +findBy(['wiki_id' => $wikiId]); + } +} diff --git a/Repository/WikiPageRepository.php b/Repository/WikiPageRepository.php new file mode 100644 index 0000000..8f9d2a2 --- /dev/null +++ b/Repository/WikiPageRepository.php @@ -0,0 +1,60 @@ +createQueryBuilder('w') + ->andWhere('w.exampleField = :val') + ->setParameter('val', $value) + ->orderBy('w.id', 'ASC') + ->setMaxResults(10) + ->getQuery() + ->getResult() + ; + } + */ + + /* + public function findOneBySomeField($value): ?WikiPage + { + return $this->createQueryBuilder('w') + ->andWhere('w.exampleField = :val') + ->setParameter('val', $value) + ->getQuery() + ->getOneOrNullResult() + ; + } + */ + + public function findByWikiId($wikiId) + { + return $this->findBy(['wiki' => $wikiId]); + } + + public function findOneByWikiIdAndName($wikiId, $name) + { + return $this->findOneBy(['wiki' => $wikiId, 'name' => $name]); + } +} diff --git a/Repository/WikiRepository.php b/Repository/WikiRepository.php new file mode 100644 index 0000000..472a140 --- /dev/null +++ b/Repository/WikiRepository.php @@ -0,0 +1,26 @@ +findOneBy(['name' => $name]); + } +} diff --git a/Resources/Services/WikiEventService.php b/Resources/Services/WikiEventService.php new file mode 100644 index 0000000..42490dd --- /dev/null +++ b/Resources/Services/WikiEventService.php @@ -0,0 +1,42 @@ +tokenStorage = $tokenStorage; + $this->wikiEventRepository = $wikiEventRepository; + $this->em = $em; + } + + public function createEvent($type, $wikiId, $data, $wikiPageId = null) + { + $user = $this->tokenStorage->getToken()->getUser(); + + $wikiEvent = new WikiEvent(); + $wikiEvent + ->setCreatedAt(time()) + ->setCreatedBy($user->getUsername()) + ->setType($type) + ->setWikiId($wikiId) + ->setWikiPageId($wikiPageId) + ->setData($data) + ; + + $this->em->persist($wikiEvent); + $this->em->flush(); + + return $wikiEvent; + } +} diff --git a/Resources/config/routing.yaml b/Resources/config/routing.yaml new file mode 100644 index 0000000..e69de29 diff --git a/Resources/config/services.xml b/Resources/config/services.xml new file mode 100644 index 0000000..639c591 --- /dev/null +++ b/Resources/config/services.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Resources/config/services.yaml b/Resources/config/services.yaml new file mode 100755 index 0000000..04d123a --- /dev/null +++ b/Resources/config/services.yaml @@ -0,0 +1,8 @@ +# config/services.yaml +services: + # ... + + # same as before + App\WikiBundle\: + resource: '%kernel.project_dir%/Linkorb/WikiBundle/*' + diff --git a/Resources/views/wiki/edit.html.twig b/Resources/views/wiki/edit.html.twig new file mode 100644 index 0000000..7c4c7b7 --- /dev/null +++ b/Resources/views/wiki/edit.html.twig @@ -0,0 +1,21 @@ +{% extends 'base.html.twig' %} + +{% block body %} +

{% if wiki.id %} Edit {% else %} Add {% endif %} Wiki

+ {{ form_start(form) }} +
+
+
+ Info + {{ form_widget(form) }} + + + + + Back + +
+
+
+ {{ form_end(form) }} +{% endblock %} \ No newline at end of file diff --git a/Resources/views/wiki/index.html.twig b/Resources/views/wiki/index.html.twig new file mode 100644 index 0000000..ec376b0 --- /dev/null +++ b/Resources/views/wiki/index.html.twig @@ -0,0 +1,60 @@ +{% extends 'base.html.twig' %} + +{% block title %}Wiki {% endblock %} + +{% block body %} +

Wiki

+ +
+ + + Add + +
+ +
+
+
+ + + + + + + + + + + {% for wiki in wikis %} + + + + + + + {% else %} + + + + {% endfor %} + +
IdNameDescriptionAction
{{ wiki.id }}{{ wiki.name }}{{ wiki.description }} + + Edit + + + Delete + + + Pages + + + + Events + +
no records found
+
+
+
+ +{% endblock %} diff --git a/Resources/views/wiki_event/index.html.twig b/Resources/views/wiki_event/index.html.twig new file mode 100644 index 0000000..5b0aa27 --- /dev/null +++ b/Resources/views/wiki_event/index.html.twig @@ -0,0 +1,50 @@ +{% extends 'base.html.twig' %} + +{% block title %}Wiki: {{ wiki.name }} :Events {% endblock %} + +{% block body %} +

Wiki: {{ wiki.name }} :Events

+ +
+ + + Back + +
+ +
+
+
+ + + + + + + + + + + {% for wikiEvent in wikiEvents %} + + + + + + + + + + + {% else %} + + + + {% endfor %} + +
IdTypeCreated AtCreated By
{{ wikiEvent.id }}{{ wikiEvent.type }}{{ wikiEvent.createdAt|date() }}{{ wikiEvent.createdBy }}
 {{ wikiEvent.data }}
no records found
+
+
+
+ +{% endblock %} diff --git a/Resources/views/wiki_page/edit.html.twig b/Resources/views/wiki_page/edit.html.twig new file mode 100644 index 0000000..fa2b839 --- /dev/null +++ b/Resources/views/wiki_page/edit.html.twig @@ -0,0 +1,42 @@ +{% extends 'base.html.twig' %} + +{% block body %} +

Wiki: {{ wikiPage.wiki.name }} :: {% if wikiPage.id %} Edit {% else %} Add {% endif %} Page

+ {{ form_start(form) }} +
+
+
+ Info + {{ form_widget(form) }} + + + + + Back + +
+
+
+ {{ form_end(form) }} +{% endblock %} + + +{% block scripts_custom %} + + + + + +{% endblock %} \ No newline at end of file diff --git a/Resources/views/wiki_page/index.html.twig b/Resources/views/wiki_page/index.html.twig new file mode 100644 index 0000000..8e7c699 --- /dev/null +++ b/Resources/views/wiki_page/index.html.twig @@ -0,0 +1,50 @@ +{% extends 'base.html.twig' %} + +{% block title %}Wiki: {{ wiki.name }} :Pages {% endblock %} + +{% block body %} +

Wiki: {{ wiki.name }} :Pages

+ +
+ + + Add + + + + Back + +
+ +
+
+
+ + + + + + + + + {% for wikiPage in wikiPages %} + + + + + {% else %} + + + + {% endfor %} + +
IdName
+ + {{ wikiPage.id }} + + {{ wikiPage.name }}
no records found
+
+
+
+ +{% endblock %} diff --git a/Resources/views/wiki_page/view.html.twig b/Resources/views/wiki_page/view.html.twig new file mode 100644 index 0000000..873bd9b --- /dev/null +++ b/Resources/views/wiki_page/view.html.twig @@ -0,0 +1,38 @@ +{% extends 'base.html.twig' %} + +{% block body %} +

+ Wiki: + + {{ wikiPage.wiki.name }} + + / + {{ wikiPage.name }} +

+ +
+ + + Back + + + + Edit + + + + Delete + +
+ +
+
+
+
+ {{ wikiPage.content|markdown }} +
+
+
+
+ +{% endblock %} diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..539266b --- /dev/null +++ b/composer.json @@ -0,0 +1,20 @@ +{ + "name": "linkorb/wiki-bundle", + "description": " Symfony 4 project Wiki Bundle", + "homepage": "https://github.com/linkorb/wiki-bundle", + "keywords": ["form", "linkorb"], + "type": "application", + "license": "proprietary", + "authors": [ + { + "name": "LinkORB Engineering", + "email": "engineering@linkorb.com", + "role": "Development" + } + ], + "autoload": { + "psr-4": { + "App\\WikiBundle\\": "" + } + } +} \ No newline at end of file