Added a simple dialog for changing user settings.

This commit is contained in:
Jan Böhmer 2019-03-15 18:04:15 +01:00
parent e28eb3b84d
commit 62fe4afd74
5 changed files with 156 additions and 31 deletions

View file

@ -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.

View file

@ -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;

View file

@ -0,0 +1,53 @@
<?php
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\LanguageType;
use Symfony\Component\Form\Extension\Core\Type\LocaleType;
use Symfony\Component\Form\Extension\Core\Type\ResetType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TimezoneType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class UserSettingsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->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,
]);
}
}

View file

@ -0,0 +1,40 @@
{% extends "main_card.html.twig" %}
{% block title %}{% trans %}user.settings.label{% endtrans %}{% endblock %}
{% block card_title %}<i class="fas fa-info-circle fa-fw" aria-hidden="true"></i>
{% trans %}user.settings.label{% endtrans %}{% endblock %}
{% block card_content %}
{{ form_start(settings_form) }}
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="data-tab" data-toggle="tab" href="#data" role="tab"
aria-controls="home" aria-selected="true">{% trans %}user_settings.data.label{% endtrans %}</a>
</li>
<li class="nav-item">
<a class="nav-link" id="profile-tab" data-toggle="tab" href="#configuration" role="tab"
aria-controls="profile" aria-selected="false">{% trans %}user_settings.configuration.label{% endtrans %}</a>
</li>
</ul>
<div class="tab-content mt-3 mb-3" id="myTabContent">
<div class="tab-pane fade show active" id="data" role="tabpanel" aria-labelledby="home-tab">
{{ form_row(settings_form.name) }}
{{ form_row(settings_form.first_name) }}
{{ form_row(settings_form.last_name) }}
{{ form_row(settings_form.department) }}
{{ form_row(settings_form.email) }}
</div>
<div class="tab-pane fade" id="configuration" role="tabpanel" aria-labelledby="profile-tab">
{{ form_row(settings_form.language) }}
{{ form_row(settings_form.timezone) }}
{{ form_row(settings_form.theme) }}
</div>
</div>
{{ form_row(settings_form.save) }}
{{ form_row(settings_form.reset) }}
{{ form_end(settings_form) }}
{% endblock %}

View file

@ -85,7 +85,7 @@
<ul class="dropdown-menu dropdown-menu-right" id="login-menu">
{% if app.user %}
<a class="dropdown-item disabled" href="#" >{% trans %}user.loggedin.label{% endtrans %} {{ app.user.firstName }} {{app.user.lastName}} ({{app.user.name}})</a>
<a class="dropdown-item" href="user_settings.php"><i class="fa fa-cogs fa-fw" aria-hidden="true"></i> {% trans %}user.settings.label{% endtrans %}</a>
<a class="dropdown-item" href="{{ path("user_settings") }}"><i class="fa fa-cogs fa-fw" aria-hidden="true"></i> {% trans %}user.settings.label{% endtrans %}</a>
<a class="dropdown-item" href="{{ path("user_info_self") }}"><i class="fa fa-info-circle fa-fw" aria-hidden="true"></i> {% trans %}user.info.label{% endtrans %}</a>
<li role="separator" class="dropdown-divider"></li>
<a class="dropdown-item" href="{{ path('logout') }}"><i class="fa fa-sign-out-alt fa-fw" aria-hidden="true"></i> {% trans %}user.logout{% endtrans %}</a>