diff --git a/app/Resources/views/base.html.twig b/app/Resources/views/base.html.twig index 4f5d87e..08efa74 100644 --- a/app/Resources/views/base.html.twig +++ b/app/Resources/views/base.html.twig @@ -46,6 +46,12 @@
  • Domů
  • +
  • + FAQ +
  • +
  • + Kontakt +
  • + + {% for flash_message in app.session.flashBag.get('notice') %} + + +
    + {{ flash_message }} +
    + {% endfor %} + {% block body %} {% endblock %}
    diff --git a/app/Resources/views/contact/contact.html.twig b/app/Resources/views/contact/contact.html.twig new file mode 100644 index 0000000..008458c --- /dev/null +++ b/app/Resources/views/contact/contact.html.twig @@ -0,0 +1,11 @@ +{% extends 'base.html.twig' %} + +{% block body %} + {{ form_start(form) }} + {{ form_row(form.email) }} + {{ form_row(form.text) }} +
    + + {{ form_end(form) }} + +{% endblock %} \ No newline at end of file diff --git a/app/Resources/views/faq/add.html.twig b/app/Resources/views/faq/add.html.twig new file mode 100644 index 0000000..71c918c --- /dev/null +++ b/app/Resources/views/faq/add.html.twig @@ -0,0 +1,11 @@ +{% extends 'base.html.twig' %} + +{% block body %} + {{ form_start(form) }} + {{ form_row(form.question) }} + {{ form_row(form.answer) }} +
    + + {{ form_end(form) }} +{% endblock %} + diff --git a/app/Resources/views/faq/edit.html.twig b/app/Resources/views/faq/edit.html.twig new file mode 100644 index 0000000..c7e6e7b --- /dev/null +++ b/app/Resources/views/faq/edit.html.twig @@ -0,0 +1,11 @@ +{% extends 'base.html.twig' %} + +{% block body %} + {{ form_start(form) }} + {{ form_row(form.question) }} + {{ form_row(form.answer) }} +
    + + {{ form_end(form) }} +{% endblock %} + diff --git a/app/Resources/views/faq/faq.html.twig b/app/Resources/views/faq/faq.html.twig new file mode 100644 index 0000000..636fb6b --- /dev/null +++ b/app/Resources/views/faq/faq.html.twig @@ -0,0 +1,12 @@ +{% extends 'base.html.twig' %} + +{% block body %} + {% for question in questions %} +
    +

    {{ question.text }}

    + + {{ answers[question.id].text }} +
    + {% endfor %} +{% endblock %} + diff --git a/app/Resources/views/faq/list.html.twig b/app/Resources/views/faq/list.html.twig new file mode 100644 index 0000000..4621960 --- /dev/null +++ b/app/Resources/views/faq/list.html.twig @@ -0,0 +1,13 @@ +{% extends 'base.html.twig' %} + +{% block body %} + Přidat + {% for question in questions %} +
    +

    {{ question.text }} Upravit

    + + {{ answers[question.id].text }} +
    + {% endfor %} +{% endblock %} + diff --git a/app/config/security.yml b/app/config/security.yml index 82c6691..35297d9 100644 --- a/app/config/security.yml +++ b/app/config/security.yml @@ -1,10 +1,22 @@ security: + role_hierarchy: + ROLE_ADMIN: ROLE_USER + encoders: + Symfony\Component\Security\Core\User\User: plaintext AppBundle\Entity\User: algorithm: bcrypt cost: 13 #cost is 13 by default, just so you know why and how to set it providers: + chain_provider: + chain: + providers: [in_memory, database_users] + in_memory: + memory: + users: + - { name: admin@shop.cz, password: admin, roles: 'ROLE_ADMIN' } + database_users: entity: { class: AppBundle:User, property: username } @@ -24,4 +36,6 @@ security: # The route name the user can go to in order to logout path: user_logout # The name of the route to redirect to after logging out - target: homepage \ No newline at end of file + target: homepage + access_control: + - { path: ^/faq/, roles: ROLE_ADMIN } \ No newline at end of file diff --git a/app/config/services.yml b/app/config/services.yml index 59f9fb4..06903a8 100644 --- a/app/config/services.yml +++ b/app/config/services.yml @@ -20,6 +20,14 @@ services: class: AppBundle\Controller\UserController autowire: true + app.controller.faq_controller: + class: AppBundle\Controller\FaqController + autowire: true + + app.controller.contact_controller: + class: AppBundle\Controller\ContactController + autowire: true + app.facade.category_facade: class: AppBundle\Facade\CategoryFacade autowire: true @@ -32,6 +40,22 @@ services: class: AppBundle\Facade\UserFacade autowire: true + app.facade.answer_facade: + class: AppBundle\Facade\AnswerFacade + autowire: true + + app.facade.question_facade: + class: AppBundle\Facade\QuestionFacade + autowire: true + + app.facade.message_facade: + class: AppBundle\Facade\MessageFacade + autowire: true + + app.facade.faq_facade: + class: AppBundle\Facade\FaqFacade + autowire: true + app.repository.category_repository: class: AppBundle\Repository\CategoryRepository factory: ['@doctrine.orm.default_entity_manager', getRepository] @@ -42,6 +66,16 @@ services: factory: ['@doctrine.orm.default_entity_manager', getRepository] arguments: ['AppBundle\Entity\Product'] + app.repository.answer_repository: + class: AppBundle\Repository\AnswerRepository + factory: ['@doctrine.orm.default_entity_manager', getRepository] + arguments: ['AppBundle\Entity\Answer'] + + app.repository.question_repository: + class: AppBundle\Repository\QuestionRepository + factory: ['@doctrine.orm.default_entity_manager', getRepository] + arguments: ['AppBundle\Entity\Question'] + encoder: class: Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder arguments: diff --git a/src/AppBundle/Controller/ContactController.php b/src/AppBundle/Controller/ContactController.php new file mode 100644 index 0000000..4d341c0 --- /dev/null +++ b/src/AppBundle/Controller/ContactController.php @@ -0,0 +1,69 @@ +formFactory = $formFactory; + $this->messageFacade = $messageFacade; + $this->router = $router; + $this->flashBag = $flashBag; + } + + /** + * @Route("/contact", name="contact") + * @Template("contact/contact.html.twig") + */ + public function contactAction(Request $request) + { + $messageVO = new MessageVO(); + $form = $this->formFactory->create(ContactFormType::class, $messageVO); + + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + $this->messageFacade->save($messageVO); + + $this->flashBag->add('notice', 'Message send.'); + + return RedirectResponse::create($this->router->generate("contact")); + } + + return [ + "form" => $form->createView() + ]; + } +} \ No newline at end of file diff --git a/src/AppBundle/Controller/FaqController.php b/src/AppBundle/Controller/FaqController.php new file mode 100644 index 0000000..01e14c2 --- /dev/null +++ b/src/AppBundle/Controller/FaqController.php @@ -0,0 +1,142 @@ +formFactory = $formFactory; + $this->questionFacade = $questionFacade; + $this->answerFacade = $answerFacade; + $this->faqFacade = $faqFacade; + $this->router = $router; + $this->flashBag = $flashBag; + } + + /** + * @Route("/faq", name="faq") + * @Template("faq/faq.html.twig") + */ + public function faqAction(Request $request) + { + $questions = $this->questionFacade->findAll(); + $answers = $this->answerFacade->findByQuestions($questions); + + return [ + "questions" => $questions, + "answers" => $answers, + ]; + } + + /** + * @Route("/faq/list", name="faq_list") + * @Template("faq/list.html.twig") + */ + public function listAction() + { + $questions = $this->questionFacade->findAll(); + $answers = $this->answerFacade->findByQuestions($questions); + + return [ + "questions" => $questions, + "answers" => $answers, + ]; + } + + /** + * @Route("/faq/add", name="faq_add") + * @Template("faq/add.html.twig") + * @param Request $request + * @return array + */ + public function addAction(Request $request) + { + $faqVO = new FaqVO(); + $form = $this->formFactory->create(FaqFormType::class, $faqVO); + + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + $this->faqFacade->insert($faqVO); + + $this->flashBag->add('notice', 'Question added.'); + + return RedirectResponse::create($this->router->generate("faq_list")); + } + + return [ + "form" => $form->createView() + ]; + } + + /** + * @Route("/faq/edit/{id}", name="faq_edit", requirements={"id": "\d+"}) + * @Template("faq/edit.html.twig") + * @param int $id + * @param Request $request + * @return array + */ + public function editAction($id, Request $request) + { + $question = $this->questionFacade->findById($id); + $answer = $this->answerFacade->findByQuestion($question); + + $faqVO = FaqVO::fromEntity($question, $answer); + $form = $this->formFactory->create(FaqFormType::class, $faqVO); + + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + $this->faqFacade->update($question, $answer, $faqVO); + + $this->flashBag->add('notice', 'Question uppdated.'); + + return RedirectResponse::create($this->router->generate("faq_list")); + } + + return [ + "form" => $form->createView() + ]; + } +} diff --git a/src/AppBundle/Entity/Answer.php b/src/AppBundle/Entity/Answer.php new file mode 100644 index 0000000..29c2a1f --- /dev/null +++ b/src/AppBundle/Entity/Answer.php @@ -0,0 +1,73 @@ +id; + } + + /** + * @return Question + */ + public function getQuestion() : Question + { + return $this->question; + } + + /** + * @param Question $question + */ + public function setQuestion(Question $question) + { + $this->question = $question; + } + + /** + * @return string + */ + public function getText() : string + { + return $this->text; + } + + /** + * @param string $text + */ + public function setText(string $text) + { + $this->text = $text; + } +} \ No newline at end of file diff --git a/src/AppBundle/Entity/Message.php b/src/AppBundle/Entity/Message.php new file mode 100644 index 0000000..cb85c62 --- /dev/null +++ b/src/AppBundle/Entity/Message.php @@ -0,0 +1,74 @@ +id; + } + + /** + * @return string + */ + public function getEmail() : string + { + return $this->email; + } + + /** + * @param string $email + */ + public function setEmail(string $email) + { + $this->email = $email; + } + + /** + * @return string + */ + public function getText(): string + { + return $this->text; + } + + /** + * @param string $text + */ + public function setText(string $text) + { + $this->text = $text; + } +} \ No newline at end of file diff --git a/src/AppBundle/Entity/Question.php b/src/AppBundle/Entity/Question.php new file mode 100644 index 0000000..f3b5d9d --- /dev/null +++ b/src/AppBundle/Entity/Question.php @@ -0,0 +1,51 @@ +id; + } + + /** + * @return string + */ + public function getText() : string + { + return $this->text; + } + + /** + * @param string $text + */ + public function setText(string $text) + { + $this->text = $text; + } +} \ No newline at end of file diff --git a/src/AppBundle/Facade/AnswerFacade.php b/src/AppBundle/Facade/AnswerFacade.php new file mode 100644 index 0000000..8555a27 --- /dev/null +++ b/src/AppBundle/Facade/AnswerFacade.php @@ -0,0 +1,66 @@ +answerRepository = $answerRepository; + $this->entityManager = $entityManager; + } + + /** + * @param Question $question + * @return Answer|null + */ + public function findByQuestion(Question $question) + { + return $this->answerRepository->findOneBy([ + "question" => $question, + ]); + } + + /** + * @param Question[] $questions + * @return Answer[]|null + */ + public function findByQuestions($questions) + { + /** @var Answer[] $answers */ + $answers = $this->answerRepository->findBy([ + "question" => $questions, + ]); + + $result = []; + foreach ($answers as $answer) { + $result[$answer->getQuestion()->getId()] = $answer; + } + + return $result; + } + + /** + * @param Answer $answer + */ + public function save(Answer $answer) + { + $this->entityManager->persist($answer); + $this->entityManager->flush($answer); + } +} \ No newline at end of file diff --git a/src/AppBundle/Facade/FaqFacade.php b/src/AppBundle/Facade/FaqFacade.php new file mode 100644 index 0000000..47cb79d --- /dev/null +++ b/src/AppBundle/Facade/FaqFacade.php @@ -0,0 +1,56 @@ +questionFacade = $questionFacade; + $this->answerFacade = $answerFacade; + } + + /** + * @param FaqVO $faqVO + */ + public function insert(FaqVO $faqVO) + { + $question = new Question(); + $answer = new Answer(); + $answer->setQuestion($question); + + $question->setText($faqVO->getQuestion()); + $answer->setText($faqVO->getAnswer()); + + $this->questionFacade->save($question); + $this->answerFacade->save($answer); + } + + /** + * @param Question $question + * @param Answer $answer + * @param FaqVO $faqVO + */ + public function update(Question $question, Answer $answer, FaqVO $faqVO) + { + $question->setText($faqVO->getQuestion()); + $answer->setText($faqVO->getAnswer()); + + $this->questionFacade->save($question); + $this->answerFacade->save($answer); + } +} \ No newline at end of file diff --git a/src/AppBundle/Facade/MessageFacade.php b/src/AppBundle/Facade/MessageFacade.php new file mode 100644 index 0000000..0a309e0 --- /dev/null +++ b/src/AppBundle/Facade/MessageFacade.php @@ -0,0 +1,35 @@ +entityManager = $entityManager; + } + + /** + * @param MessageVO $messageVO + */ + public function save(MessageVO $messageVO) + { + $message = new Message(); + + $message->setEmail($messageVO->getEmail()); + $message->setText($messageVO->getText()); + + $this->entityManager->persist($message); + $this->entityManager->flush($message); + } +} \ No newline at end of file diff --git a/src/AppBundle/Facade/QuestionFacade.php b/src/AppBundle/Facade/QuestionFacade.php new file mode 100644 index 0000000..660095d --- /dev/null +++ b/src/AppBundle/Facade/QuestionFacade.php @@ -0,0 +1,53 @@ +questionRepository = $questionRepository; + $this->entityManager = $entityManager; + } + + /** + * @return Question + */ + public function findById($id) + { + return $this->questionRepository->findOneBy([ + 'id' => $id, + ]); + } + + /** + * @return Question[] + */ + public function findAll() + { + return $this->questionRepository->findAll(); + } + + /** + * @param Question $question + */ + public function save(Question $question) + { + $this->entityManager->persist($question); + $this->entityManager->flush($question); + } +} \ No newline at end of file diff --git a/src/AppBundle/FormType/ContactFormType.php b/src/AppBundle/FormType/ContactFormType.php new file mode 100644 index 0000000..48f4aba --- /dev/null +++ b/src/AppBundle/FormType/ContactFormType.php @@ -0,0 +1,33 @@ +add("email", EmailType::class, [ + "label" => "E-mail", + "attr" => [ + "class" => "form-control", + ], + "constraints" => [ + new NotBlank(["message" => "Prosím vyplňte Váš e-mail"]), + ], + ])->add("text", TextareaType::class, [ + "label" => "Zpráva", + "attr" => [ + "class" => "form-control", + ], + "constraints" => [ + new NotBlank(["message" => "Prosím napište text zprávy"]), + ], + ]); + } +} \ No newline at end of file diff --git a/src/AppBundle/FormType/FaqFormType.php b/src/AppBundle/FormType/FaqFormType.php new file mode 100644 index 0000000..1dcb149 --- /dev/null +++ b/src/AppBundle/FormType/FaqFormType.php @@ -0,0 +1,32 @@ +add("question", TextareaType::class, [ + "label" => "Otázka", + "attr" => [ + "class" => "form-control", + ], + "constraints" => [ + new NotBlank(["message" => "Prosím napište text otázky."]), + ], + ])->add("answer", TextareaType::class, [ + "label" => "Odpověď", + "attr" => [ + "class" => "form-control", + ], + "constraints" => [ + new NotBlank(["message" => "Prosím napište text odpovědi."]), + ], + ]); + } +} \ No newline at end of file diff --git a/src/AppBundle/FormType/VO/FaqVO.php b/src/AppBundle/FormType/VO/FaqVO.php new file mode 100644 index 0000000..efed62b --- /dev/null +++ b/src/AppBundle/FormType/VO/FaqVO.php @@ -0,0 +1,61 @@ +question; + } + + /** + * @param null|string $question + */ + public function setQuestion($question) + { + $this->question = $question; + } + + /** + * @return null|string + */ + public function getAnswer() + { + return $this->answer; + } + + /** + * @param null|string $answer + */ + public function setAnswer($answer) + { + $this->answer = $answer; + } + + /** + * @param Question $question + * @param Answer $answer + * @return FaqVO + */ + public static function fromEntity(Question $question, Answer $answer) + { + $faqVO = new FaqVO(); + $faqVO->setQuestion($question->getText()); + $faqVO->setAnswer($answer->getText()); + + return $faqVO; + } +} \ No newline at end of file diff --git a/src/AppBundle/FormType/VO/MessageVO.php b/src/AppBundle/FormType/VO/MessageVO.php new file mode 100644 index 0000000..b30bd64 --- /dev/null +++ b/src/AppBundle/FormType/VO/MessageVO.php @@ -0,0 +1,44 @@ +email; + } + + /** + * @param string $email + */ + public function setEmail(string $email) + { + $this->email = $email; + } + + /** + * @return string + */ + public function getText() + { + return $this->text; + } + + /** + * @param string $text + */ + public function setText(string $text) + { + $this->text = $text; + } +} \ No newline at end of file diff --git a/src/AppBundle/Repository/AnswerRepository.php b/src/AppBundle/Repository/AnswerRepository.php new file mode 100644 index 0000000..76118cd --- /dev/null +++ b/src/AppBundle/Repository/AnswerRepository.php @@ -0,0 +1,21 @@ +_em->createQueryBuilder() + ->select('*') + ->from(Answer::class, 'a') + ->where('a.question = :question') + ->setParameter("question", $question) + ->getQuery() + ->getResult(); + } +} \ No newline at end of file diff --git a/src/AppBundle/Repository/QuestionRepository.php b/src/AppBundle/Repository/QuestionRepository.php new file mode 100644 index 0000000..f95054f --- /dev/null +++ b/src/AppBundle/Repository/QuestionRepository.php @@ -0,0 +1,9 @@ +