Skip to content

Commit

Permalink
feat: 🎸 impl profile crud
Browse files Browse the repository at this point in the history
  • Loading branch information
ttskch committed Dec 24, 2020
1 parent 37345f7 commit b55c6f3
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 1 deletion.
61 changes: 61 additions & 0 deletions src/Controller/UserController.php
Expand Up @@ -7,6 +7,7 @@
use App\Entity\User;
use App\Form\UserChangePasswordType;
use App\Form\UserEditType;
use App\Form\UserProfileEditType;
use App\Form\UserType;
use App\Repository\UserRepository;
use App\Routing\ReturnToAwareControllerTrait;
Expand Down Expand Up @@ -66,6 +67,66 @@ public function logout(): Response
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}

/**
* @Route("/profile", name="profile_show", methods={"GET"})
*/
public function profileShow(): Response
{
return $this->render('user/profile_show.html.twig', [
'user' => $this->getUser(),
]);
}

/**
* @Route("/profile/edit", name="profile_edit", methods={"GET", "POST"})
*/
public function profileEdit(Request $request): Response
{
$form = $this->createForm(UserProfileEditType::class, $user = $this->getUser());
$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
$this->em->persist($user);
$this->em->flush();

$this->addFlash('success', 'Profile is successfully updated.');

return $this->redirectToRouteOrReturn('user_profile_show');
}

return $this->render('user/profile_edit.html.twig', [
'user' => $user,
'form' => $form->createView(),
]);
}

/**
* @Route("/profile/change_password", name="profile_change_password", methods={"GET", "POST"})
*/
public function profileChangePassword(Request $request): Response
{
$user = $this->getUser();

$form = $this->createForm(UserChangePasswordType::class);
$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
$user->plainPassword = $form->get('newPassword')->getData();

$this->em->persist($user);
$this->em->flush();

$this->addFlash('success', 'Password is successfully updated.');

return $this->redirectToRouteOrReturn('user_profile_show');
}

return $this->render('user/profile_change_password.html.twig', [
'user' => $user,
'form' => $form->createView(),
]);
}

/**
* @Route("/", name="index", methods={"GET"})
*/
Expand Down
30 changes: 30 additions & 0 deletions src/Form/UserProfileEditType.php
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace App\Form;

use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class UserProfileEditType extends UserType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);

$builder
->remove('plainPassword')
->remove('roles')
;
}

public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);

$resolver->setDefaults([
'validation_groups' => [],
]);
}
}
19 changes: 18 additions & 1 deletion templates/base.html.twig
Expand Up @@ -58,7 +58,7 @@
<i class="fa fa-bars"></i>
</button>
<div class="collapse navbar-collapse" id="navbar-collapse-1">
<ul class="navbar-nav">
<ul class="navbar-nav mr-auto">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbar-dropdown-1" role="button" data-toggle="dropdown">
{{ 'Menu'|trans }}
Expand All @@ -68,6 +68,23 @@
</div>
</li>
</ul>

<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbar-dropdown-2" role="button" data-toggle="dropdown">
<i class="fa fa-user"></i> {{ app.user }}
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbar-dropdown-2">
<a class="dropdown-item" href="{{ path('user_profile_show') }}">{{ 'Profile'|trans }}</a>
<div class="dropdown-divider"></div>
{% if is_granted('ROLE_PREVIOUS_ADMIN') %}
<a class="dropdown-item" href="{{ path('home_index', {_switch_user: '_exit'}) }}"><i class="fa fa-sign-out-alt"></i> {{ 'End impersonation'|trans }}</a>
{% else %}
<a class="dropdown-item" href="{{ path('user_logout') }}"><i class="fa fa-sign-out-alt"></i> {{ 'Logout'|trans }}</a>
{% endif %}
</div>
</li>
</ul>
</div>
{% endif %}
</div>
Expand Down
30 changes: 30 additions & 0 deletions templates/user/_form.html.twig
Expand Up @@ -33,6 +33,26 @@
{{ form_widget(form._token) }}
{{ form_end(form, {render_rest: false}) }}

{% elseif type == 'profile_edit' %}

{{ form_start(form) }}
{{ form_row(form.email) }}
<div class="form-group row">
<label class="col-form-label col-sm-3">{{ 'Password'|trans }}</label>
<div class="col-sm-9">
<div class="form-control-plaintext">
<a href="{{ path('user_profile_change_password') }}" tabindex="-1">{{ 'Change the password'|trans }}</a>
</div>
</div>
</div>
{{ form_row(form.displayName) }}
<div class="float-right">
<button type="submit" class="btn btn-primary float-right ml-2">{{ 'Save'|trans }}</button>
<a href="{{ path('user_profile_show') }}" class="btn btn-outline-secondary">{{ 'Cancel'|trans }}</a>
</div>
{{ form_widget(form._token) }}
{{ form_end(form, {render_rest: false}) }}

{% elseif type == 'change_password' %}

{{ form_start(form) }}
Expand All @@ -43,4 +63,14 @@
</div>
{{ form_end(form) }}

{% elseif type == 'profile_change_password' %}

{{ form_start(form) }}
{{ form_rest(form) }}
<div class="float-right">
<button type="submit" class="btn btn-primary float-right ml-2">{{ 'Save'|trans }}</button>
<a href="{{ path('user_profile_edit') }}" class="btn btn-outline-secondary">{{ 'Cancel'|trans }}</a>
</div>
{{ form_end(form) }}

{% endif %}
17 changes: 17 additions & 0 deletions templates/user/profile_change_password.html.twig
@@ -0,0 +1,17 @@
{% extends 'base.html.twig' %}

{% block subtitle %}{{ 'Change password'|trans }}{% endblock %}

{% block content_container %}
{% include 'widgets/breadcrumb.html.twig' with {items: [
{label: 'Profile'|trans, path: path('user_profile_show')},
{label: 'Edit'|trans, path: path('user_profile_edit')},
{label: 'Change password'|trans},
]} %}

{% include 'widgets/content-navbar.html.twig' with { title: block('subtitle') } %}

<div class="container ml-0 px-0">
{% include 'user/_form.html.twig' with {type: 'profile_change_password'} %}
</div>
{% endblock %}
16 changes: 16 additions & 0 deletions templates/user/profile_edit.html.twig
@@ -0,0 +1,16 @@
{% extends 'base.html.twig' %}

{% block subtitle %}{{ 'Edit profile'|trans }}{% endblock %}

{% block content_container %}
{% include 'widgets/breadcrumb.html.twig' with {items: [
{label: 'Profile'|trans, path: path('user_profile_show')},
{label: 'Edit'|trans},
]} %}

{% include 'widgets/content-navbar.html.twig' with { title: block('subtitle') } %}

<div class="container ml-0 px-0">
{% include 'user/_form.html.twig' with {type: 'profile_edit'} %}
</div>
{% endblock %}
19 changes: 19 additions & 0 deletions templates/user/profile_show.html.twig
@@ -0,0 +1,19 @@
{% extends 'base.html.twig' %}

{% block subtitle %}{{ 'Profile'|trans }}{% endblock %}

{% block content_container %}
{% include 'widgets/breadcrumb.html.twig' with {items: [
{label: 'Profile'|trans},
]} %}

{% embed 'widgets/content-navbar.html.twig' with { title: block('subtitle') } %}
{% block nav_items %}
<li class="nav-item">
<a href="{{ path('user_profile_edit') }}" class="nav-link">{{ 'Edit'|trans }}</a>
</li>
{% endblock %}
{% endembed %}

{% include 'user/_detail.html.twig' %}
{% endblock %}
5 changes: 5 additions & 0 deletions translations/messages.ja.yaml
Expand Up @@ -9,6 +9,9 @@ Password: パスワード
Remember me: ログイン状態を記憶する

Menu: メニュー
Profile: ユーザー情報
End impersonation: 代理ログイン終了
Logout: ログアウト

User: ユーザー
Id: ID
Expand All @@ -22,6 +25,7 @@ Add user: ユーザー追加
User detail: ユーザー詳細
Edit user: ユーザー編集
Change password: パスワード変更
Edit profile: ユーザー情報編集
Add: 追加
Show: 詳細
Edit: 編集
Expand All @@ -40,3 +44,4 @@ User is successfully updated.: ユーザーの編集が完了しました。
Password is successfully updated.: パスワードの変更が完了しました。
User is successfully deleted.: ユーザーの削除が完了しました。
User cannot be deleted because it owns some related contents.: そのユーザーに紐づいているデータがあるため削除できません。
Profile is successfully updated.: ユーザー情報の編集が完了しました。

0 comments on commit b55c6f3

Please sign in to comment.