diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 6819a285..d5811bcd 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -33,8 +33,11 @@ namespace App\Controller; use App\Entity\User; +use App\Form\UserSettingsType; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Asset\Packages; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; class UserController extends AbstractController @@ -65,6 +68,32 @@ class UserController extends AbstractController ]); } + /** + * @Route("/user/settings", name="user_settings") + */ + public function userSettings(Request $request, EntityManagerInterface $em) + { + $user = $this->getUser(); + + //When user change its settings, he should be logged in fully. + $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY'); + + + $form = $this->createForm(UserSettingsType::class, $user); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $em->persist($user); + $em->flush(); + $this->addFlash('success', 'user.settings.saved_flash'); + } + + return $this->render('Users/user_settings.html.twig', [ + "settings_form" => $form->createView() + ]); + } + /** * Get either a Gravatar URL or complete image tag for a specified email address. diff --git a/src/Entity/User.php b/src/Entity/User.php index c969a006..49bf9fd8 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -34,6 +34,7 @@ namespace App\Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\UserInterface; +use Symfony\Component\Validator\Constraints as Assert; /** * This entity represents a user, which can log in and have permissions. @@ -53,6 +54,7 @@ class User extends NamedDBElement implements UserInterface /** * @ORM\Column(type="string", length=180, unique=true) + * @Assert\NotBlank */ protected $name; @@ -62,51 +64,52 @@ class User extends NamedDBElement implements UserInterface //protected $roles = []; /** - * @var string The hashed password - * @ORM\Column(type="string") + * @var string|null The hashed password + * @ORM\Column(type="string", nullable=true) */ protected $password; /** - * @var string The first name of the User - * @ORM\Column(type="string", length=255) + * @var string|null The first name of the User + * @ORM\Column(type="string", length=255, nullable=true) */ protected $first_name = ""; /** - * @var string The last name of the User - * @ORM\Column(type="string", length=255) + * @var string|null The last name of the User + * @ORM\Column(type="string", length=255, nullable=true) */ protected $last_name = ""; /** - * @var string The department the user is working - * @ORM\Column(type="string", length=255) + * @var string|null The department the user is working + * @ORM\Column(type="string", length=255, nullable=true) */ protected $department = ""; /** - * @var string The email address of the user - * @ORM\Column(type="string", length=255) + * @var string|null The email address of the user + * @ORM\Column(type="string", length=255, nullable=true) + * @Assert\Email() */ protected $email = ""; /** - * @var string The language/locale the user prefers - * @ORM\Column(type="string", name="config_language") + * @var string|null The language/locale the user prefers + * @ORM\Column(type="string", name="config_language", nullable=true) */ protected $language = ""; /** - * @var string The timezone the user prefers - * @ORM\Column(type="string", name="config_timezone") + * @var string|null The timezone the user prefers + * @ORM\Column(type="string", name="config_timezone", nullable=true) */ protected $timezone = ""; /** - * @var string The theme - * @ORM\Column(type="string", name="config_theme") + * @var string|null The theme + * @ORM\Column(type="string", name="config_theme", nullable=true) */ protected $theme = ""; @@ -198,7 +201,7 @@ class User extends NamedDBElement implements UserInterface /** * @return string */ - public function getFirstName(): string + public function getFirstName(): ?string { return $this->first_name; } @@ -207,7 +210,7 @@ class User extends NamedDBElement implements UserInterface * @param string $first_name * @return User */ - public function setFirstName(string $first_name): User + public function setFirstName(?string $first_name): User { $this->first_name = $first_name; return $this; @@ -216,7 +219,7 @@ class User extends NamedDBElement implements UserInterface /** * @return string */ - public function getLastName(): string + public function getLastName(): ?string { return $this->last_name; } @@ -225,7 +228,7 @@ class User extends NamedDBElement implements UserInterface * @param string $last_name * @return User */ - public function setLastName(string $last_name): User + public function setLastName(?string $last_name): User { $this->last_name = $last_name; return $this; @@ -234,7 +237,7 @@ class User extends NamedDBElement implements UserInterface /** * @return string */ - public function getDepartment(): string + public function getDepartment(): ?string { return $this->department; } @@ -243,7 +246,7 @@ class User extends NamedDBElement implements UserInterface * @param string $department * @return User */ - public function setDepartment(string $department): User + public function setDepartment(?string $department): User { $this->department = $department; return $this; @@ -252,7 +255,7 @@ class User extends NamedDBElement implements UserInterface /** * @return string */ - public function getEmail(): string + public function getEmail(): ?string { return $this->email; } @@ -261,7 +264,7 @@ class User extends NamedDBElement implements UserInterface * @param string $email * @return User */ - public function setEmail(string $email): User + public function setEmail(?string $email): User { $this->email = $email; return $this; @@ -270,7 +273,7 @@ class User extends NamedDBElement implements UserInterface /** * @return string */ - public function getLanguage(): string + public function getLanguage(): ?string { return $this->language; } @@ -279,7 +282,7 @@ class User extends NamedDBElement implements UserInterface * @param string $language * @return User */ - public function setLanguage(string $language): User + public function setLanguage(?string $language): User { $this->language = $language; return $this; @@ -288,7 +291,7 @@ class User extends NamedDBElement implements UserInterface /** * @return string */ - public function getTimezone(): string + public function getTimezone(): ?string { return $this->timezone; } @@ -297,7 +300,7 @@ class User extends NamedDBElement implements UserInterface * @param string $timezone * @return User */ - public function setTimezone(string $timezone): User + public function setTimezone(?string $timezone): User { $this->timezone = $timezone; return $this; @@ -306,7 +309,7 @@ class User extends NamedDBElement implements UserInterface /** * @return string */ - public function getTheme(): string + public function getTheme(): ?string { return $this->theme; } @@ -315,7 +318,7 @@ class User extends NamedDBElement implements UserInterface * @param string $theme * @return User */ - public function setTheme(string $theme): User + public function setTheme(?string $theme): User { $this->theme = $theme; return $this; diff --git a/src/Form/UserSettingsType.php b/src/Form/UserSettingsType.php new file mode 100644 index 00000000..9e16d3fb --- /dev/null +++ b/src/Form/UserSettingsType.php @@ -0,0 +1,53 @@ +add('name', TextType::class, ['label'=>'user.username.label']) + ->add('first_name', TextType::class, ['required' => false, + 'label'=>'user.firstName.label']) + ->add('last_name', TextType::class, ['required' => false, + 'label'=>'user.lastName.label']) + ->add('department', TextType::class, ['required' => false, + 'label'=>'user.department.label']) + ->add('email', EmailType::class, ['required' => false, + 'label'=>'user.email.label']) + ->add('language', LocaleType::class, ['required' => false, + 'attr'=>['class'=> 'selectpicker', 'data-live-search' => true] + , 'placeholder' => 'user_settings.language.placeholder', 'label'=>'user.language_select']) + ->add('timezone', TimezoneType::class, ['required' => false, + 'attr'=>['class'=> 'selectpicker', 'data-live-search' => true], + 'placeholder' => 'user_settings.timezone.placeholder', 'label'=>'user.timezone.label']) + ->add('theme', ChoiceType::class, ['required' => false, + 'placeholder' => 'user_settings.theme.placeholder', 'label'=>'user.theme.label']) + + //Buttons + ->add('save', SubmitType::class, ['label' => 'save']) + ->add('reset', ResetType::class, ['label' => 'reset']); + ; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => User::class, + ]); + } +} diff --git a/templates/Users/user_settings.html.twig b/templates/Users/user_settings.html.twig new file mode 100644 index 00000000..7444ed3f --- /dev/null +++ b/templates/Users/user_settings.html.twig @@ -0,0 +1,40 @@ +{% extends "main_card.html.twig" %} + +{% block title %}{% trans %}user.settings.label{% endtrans %}{% endblock %} + +{% block card_title %} + {% trans %}user.settings.label{% endtrans %}{% endblock %} + +{% block card_content %} + {{ form_start(settings_form) }} + +
+