diff --git a/.gitignore b/.gitignore index 947ec6a..a9b5776 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ /vendor/ /web/bundles/ composer.lock +composer.phar diff --git a/app/Resources/views/base.html.twig b/app/Resources/views/base.html.twig index 7e93622..281832b 100644 --- a/app/Resources/views/base.html.twig +++ b/app/Resources/views/base.html.twig @@ -49,7 +49,8 @@
- - + + diff --git a/app/Resources/views/user/password.html.twig b/app/Resources/views/user/password.html.twig new file mode 100644 index 0000000..a6383fc --- /dev/null +++ b/app/Resources/views/user/password.html.twig @@ -0,0 +1,23 @@ +{% extends 'base.html.twig' %} + +{% block body %} + {% for flash_message in app.session.flashBag.get('error') %} +
+
+ {{ flash_message }} +
+
+ {% endfor %} + {% for flash_message in app.session.flashBag.get('success') %} +
+
+ {{ flash_message }} +
+
+ {% endfor %} + {{ form_start(form, {'attr': {'novalidate': 'novalidate'}}) }} + {{ form_widget(form) }} +
+ + {{ form_end(form) }} +{% endblock %} \ No newline at end of file diff --git a/app/Resources/views/user/profile.html.twig b/app/Resources/views/user/profile.html.twig new file mode 100644 index 0000000..6273aa5 --- /dev/null +++ b/app/Resources/views/user/profile.html.twig @@ -0,0 +1,9 @@ +{% extends 'base.html.twig' %} + +{% block body %} + {{ form_start(form, {'attr': {'novalidate': 'novalidate'}}) }} + {{ form_widget(form) }} +
+ + {{ form_end(form) }} +{% endblock %} \ No newline at end of file diff --git a/app/Resources/views/user/registration.html.twig b/app/Resources/views/user/registration.html.twig index 905d379..5dad944 100644 --- a/app/Resources/views/user/registration.html.twig +++ b/app/Resources/views/user/registration.html.twig @@ -1,10 +1,15 @@ {% extends 'base.html.twig' %} {% block body %} - {{ form_start(form) }} + {{ form_start(form, {'attr': {'novalidate': 'novalidate'}}) }} {{ form_row(form.username) }} {{ form_row(form.plainPassword.first) }} {{ form_row(form.plainPassword.second) }} +

+ {{ form_row(form.fullName) }} + {{ form_row(form.address) }} + {{ form_row(form.phone) }} + {{ form_row(form.email) }}
{{ form_end(form) }} diff --git a/app/config/security.yml b/app/config/security.yml index 82c6691..1ab8aed 100644 --- a/app/config/security.yml +++ b/app/config/security.yml @@ -14,6 +14,8 @@ security: anonymous: true + provider: database_users + form_login: check_path: user_login login_path: user_login @@ -24,4 +26,7 @@ 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: ^/uzivatel, roles: IS_AUTHENTICATED_REMEMBERED } \ No newline at end of file diff --git a/composer.json b/composer.json index 88499d0..e1f47a5 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,8 @@ "symfony/polyfill-apcu": "^1.0", "sensio/distribution-bundle": "^5.0", "sensio/framework-extra-bundle": "^3.0.2", - "incenteev/composer-parameter-handler": "^2.0" + "incenteev/composer-parameter-handler": "^2.0", + "symfony/intl": "^3.1" }, "require-dev": { "sensio/generator-bundle": "^3.0", diff --git a/src/AppBundle/Controller/UserController.php b/src/AppBundle/Controller/UserController.php index d0958e3..61dd015 100644 --- a/src/AppBundle/Controller/UserController.php +++ b/src/AppBundle/Controller/UserController.php @@ -2,6 +2,8 @@ namespace AppBundle\Controller; use AppBundle\Entity\User; use AppBundle\Facade\UserFacade; +use AppBundle\FormType\PasswordFormType; +use AppBundle\FormType\ProfileFormType; use AppBundle\FormType\RegistrationFormType; use Doctrine\ORM\EntityManager; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; @@ -12,6 +14,7 @@ use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; use Symfony\Component\Routing\RouterInterface; use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface; +use Symfony\Component\Security\Core\Exception\AccessDeniedException; /** @@ -91,6 +94,93 @@ public function loginAction() ]; } + /** + * @Route("/uzivatel/profil", name="user_profile") + * @Template("user/profile.html.twig") + * + * @param Request $request + * @return RedirectResponse|array + */ + public function profileAction(Request $request) + { + $user = $this->userFacade->getUser(); + + $form = $this->formFactory->create(ProfileFormType::class, $user); + + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + + $this->entityManager->persist($user); + $this->entityManager->flush(); + + return RedirectResponse::create($this->router->generate("homepage")); + } + + return [ + "form" => $form->createView(), + "user" => $this->userFacade->getUser(), + ]; + } + + /** + * @Route("/uzivatel/heslo", name="user_password") + * @Template("user/password.html.twig") + * + * @param Request $request + * @return RedirectResponse|array + */ + public function passwordAction(Request $request) + { + $user = $this->userFacade->getUser(); + + $form = $this->formFactory->create(PasswordFormType::class); + + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + $oldPasswordPlain = $form->get('oldPassword')->getData(); + $newPasswordPlain = $form->get('plainPassword')->getData(); + + if (empty(trim($oldPasswordPlain)) || empty(trim($newPasswordPlain))) { + $request->getSession()->getFlashBag()->add( + 'error', + 'Staré nebo nové heslo nebylo vyplněno..' + ); + return [ + "form" => $form->createView(), + "user" => $this->userFacade->getUser(), + ]; + } + + if($this->passwordEncoder->isPasswordValid( + $user->getPassword(), + $oldPasswordPlain, + $user->getSalt() + )) { + $newPassword = $this->passwordEncoder->encodePassword($newPasswordPlain, $user->getSalt()); + $user->setPassword($newPassword); + + $this->entityManager->persist($user); + $this->entityManager->flush(); + $request->getSession()->getFlashBag()->add( + 'success', + 'Vaše heslo bylo změněno!' + ); + } else { + $request->getSession()->getFlashBag()->add( + 'error', + 'Vaše staré heslo se neshoduje. Zkuste to prosím znovu!' + ); + } + + return RedirectResponse::create($this->router->generate("user_password")); + } + + return [ + "form" => $form->createView(), + "user" => $this->userFacade->getUser(), + ]; + } + /** * @Route("/odhlasit", name="user_logout") */ diff --git a/src/AppBundle/Entity/User.php b/src/AppBundle/Entity/User.php index 5dd2213..b43361c 100644 --- a/src/AppBundle/Entity/User.php +++ b/src/AppBundle/Entity/User.php @@ -24,14 +24,15 @@ class User implements UserInterface private $id; /** - * @ORM\Column(type="string", length=255, unique=true, name="email") + * @ORM\Column(type="string", length=255, unique=true, name="username") + * @Assert\Blank(groups={"onlyPassword"}) * @Assert\NotBlank() - * @Assert\Email() */ private $username; /** * @ORM\Column(type="string", length=64) + * @Assert\NotBlank(groups={"onlyProfile"}) */ private $password; @@ -41,6 +42,32 @@ class User implements UserInterface */ private $plainPassword; + /** + * @ORM\Column(type="string", length=255, name="full_name", nullable=true) + */ + private $fullName; + + /** + * @ORM\Column(type="string", length=255, name="address", nullable=true) + */ + private $address; + + /** + * @ORM\Column(type="string", length=13, name="phone", nullable=true) + * @Assert\Regex( + * pattern="/^(\+420)? ?[1-9][0-9]{2} ?[0-9]{3} ?[0-9]{3}$/i", + * htmlPattern="^(\+420)? ?[1-9][0-9]{2} ?[0-9]{3} ?[0-9]{3}$", + * message="Zkontrolujte formát telefonního čísla (+420 xxx xxx xxx)" + * ) + */ + private $phone; + + /** + * @ORM\Column(type="string", length=100, unique=true, name="email", nullable=true) + * @Assert\Email() + */ + private $email; + /** * @return int */ @@ -129,4 +156,100 @@ public function eraseCredentials() return; } + + /** + * Set fullName + * + * @param string $fullName + * + * @return User + */ + public function setFullName($fullName) + { + $this->fullName = $fullName; + + return $this; + } + + /** + * Get fullName + * + * @return string + */ + public function getFullName() + { + return $this->fullName; + } + + /** + * Set phone + * + * @param string $phone + * + * @return User + */ + public function setPhone($phone) + { + $this->phone = $phone; + + return $this; + } + + /** + * Get phone + * + * @return string + */ + public function getPhone() + { + return $this->phone; + } + + /** + * Set email + * + * @param string $email + * + * @return User + */ + public function setEmail($email) + { + $this->email = $email; + + return $this; + } + + /** + * Get email + * + * @return string + */ + public function getEmail() + { + return $this->email; + } + + /** + * Set address + * + * @param string $address + * + * @return User + */ + public function setAddress($address) + { + $this->address = $address; + + return $this; + } + + /** + * Get address + * + * @return string + */ + public function getAddress() + { + return $this->address; + } } diff --git a/src/AppBundle/FormType/PasswordFormType.php b/src/AppBundle/FormType/PasswordFormType.php new file mode 100644 index 0000000..b59d905 --- /dev/null +++ b/src/AppBundle/FormType/PasswordFormType.php @@ -0,0 +1,49 @@ +add("oldPassword", PasswordType::class, [ + "label" => "Aktuální heslo *", + "attr" => [ + "class" => "form-control", + ], + "required" => true + ]) + ->add("plainPassword", RepeatedType::class, [ + "type" => PasswordType::class, + "first_options" => [ + "label" => "Nové heslo *", + "attr" => [ + "class" => "form-control", + ], + ], + "second_options" => [ + "label" => "Nové heslo znovu *", + "attr" => [ + "class" => "form-control", + ], + ], + "required" => true + ]); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(array( + 'validation_groups' => ['onlyPassword'] + )); + } +} \ No newline at end of file diff --git a/src/AppBundle/FormType/ProfileFormType.php b/src/AppBundle/FormType/ProfileFormType.php new file mode 100644 index 0000000..fc08232 --- /dev/null +++ b/src/AppBundle/FormType/ProfileFormType.php @@ -0,0 +1,52 @@ +add("fullName", TextType::class, [ + "label" => "Jméno", + "attr" => [ + "class" => "form-control", + ], + ]) + ->add("address", TextareaType::class, [ + "label" => "Adresa", + "attr" => [ + "class" => "form-control", + ], + ]) + ->add("phone", TextType::class, [ + "label" => "Telefon", + "attr" => [ + "class" => "form-control", + ], + ]) + ->add("email", EmailType::class, [ + "label" => "Email", + "attr" => [ + "class" => "form-control", + ], + ]); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(array( + "data_class" => User::class, + 'validation_groups' => ['onlyProfile'] + )); + } +} \ No newline at end of file diff --git a/src/AppBundle/FormType/RegistrationFormType.php b/src/AppBundle/FormType/RegistrationFormType.php index 0e65ec6..96c3f83 100644 --- a/src/AppBundle/FormType/RegistrationFormType.php +++ b/src/AppBundle/FormType/RegistrationFormType.php @@ -6,6 +6,8 @@ use Symfony\Component\Form\Extension\Core\Type\EmailType; use Symfony\Component\Form\Extension\Core\Type\PasswordType; use Symfony\Component\Form\Extension\Core\Type\RepeatedType; +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; @@ -18,26 +20,52 @@ class RegistrationFormType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add("username", EmailType::class, [ - "label" => "E-mail", + ->add("username", TextType::class, [ + "label" => "Uživatelské jméno *", "attr" => [ "class" => "form-control", ], + "required" => true ]) ->add("plainPassword", RepeatedType::class, [ "type" => PasswordType::class, "first_options" => [ - "label" => "Heslo", + "label" => "Heslo *", "attr" => [ "class" => "form-control", ], ], "second_options" => [ - "label" => "Heslo znova", + "label" => "Heslo znovu *", "attr" => [ "class" => "form-control", ], ], + "required" => true + ]) + ->add("fullName", TextType::class, [ + "label" => "Jméno", + "attr" => [ + "class" => "form-control", + ], + ]) + ->add("address", TextareaType::class, [ + "label" => "Adresa", + "attr" => [ + "class" => "form-control", + ], + ]) + ->add("phone", TextType::class, [ + "label" => "Telefon", + "attr" => [ + "class" => "form-control", + ], + ]) + ->add("email", EmailType::class, [ + "label" => "Email", + "attr" => [ + "class" => "form-control", + ], ]); } diff --git a/web/config.php b/web/config.php index 1368c8a..a031a3a 100644 --- a/web/config.php +++ b/web/config.php @@ -38,9 +38,216 @@ Symfony Configuration Checker - - -