Skip to content

Commit

Permalink
Simplify profile editing / registration
Browse files Browse the repository at this point in the history
  • Loading branch information
core23 committed Oct 9, 2021
1 parent 65675d7 commit 7ae0454
Show file tree
Hide file tree
Showing 20 changed files with 161 additions and 533 deletions.
5 changes: 0 additions & 5 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,9 @@ All available configuration options are listed below with their default values.
use_listener: true
use_flash_notifications: true
use_authentication_listener: true
profile:
form:
model: Nucleos\ProfileBundle\Form\Model\Profile
registration:
confirmation:
from_email: ~ # Required
enabled: false # change to true for required email confirmation
form:
model: Nucleos\ProfileBundle\Form\Model\Registration
service:
mailer: nucleos_profile.mailer.default
55 changes: 48 additions & 7 deletions docs/customize_profile.rst
Original file line number Diff line number Diff line change
@@ -1,15 +1,56 @@
Customize Profile
=================

.. note::
If the user is allowed to change some date, you can modify the profile form. It is possible to add, remove or modify form fields provided by NucleosProfileBundle.

Work in progress!

Add more fields
---------------
How to customize a Form
-----------------------

- Extend ``Nucleos\ProfileBundle\Form\Model\Profile``
- Add custom form model to configuration
- Use symfony FormExtensions
If you want to modify the Profile form in your project there are a few steps that you should take. For example if you would like to add checkbox for accepting terms and conditions you will have to follow these steps:

1. Extend ``Nucleos\UserBundle\Model\User\User``

.. code-block:: php-annotations
namespace App\Model;
use Nucleos\UserBundle\Model\User as BaseUser;
class User extends BaseUser
{
protected ?bool $termsAccepted = false;
public function gettermsAccepted(): ?bool
{
return $this->termsAccepted;
}
public function setTermsAccepted(?bool $termsAccepted): void
{
$this->termsAccepted = $termsAccepted;
}
}
2. Use Symfony Form Extensions to add fields. You can use builder to remove or modify fields as well.

.. code-block:: php-annotations
namespace App\Form\Type;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormBuilderInterface;
class ProfileFormType extends AbstractTypeExtension
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('termsAccepted', CheckboxType::class);
}
public static function getExtendedTypes(): iterable
{
return ['Nucleos\ProfileBundle\Form\Type\ProfileFormType'];
}
}
38 changes: 7 additions & 31 deletions docs/customize_registration.rst
Original file line number Diff line number Diff line change
@@ -1,60 +1,37 @@
Customize Registration
======================

.. note::

Work in progress!


Your business needs might require changes in registration form. It is possible to add, remove or modify form fields provided by NucleosProfileBundle.

How to customize a Form
-----------------------

If you want to modify the Registration form in your project there are a few steps that you should take. For example if you would like to add checkbox for accepting terms and conditions you will have to follow these steps:

1. Extend ``Nucleos\ProfileBundle\Form\Model\Registration``
1. Extend ``Nucleos\UserBundle\Model\User\User``

.. code-block:: php-annotations
namespace App\Form\Model;
namespace App\Model;
use Nucleos\ProfileBundle\Form\Model\Registration as BaseRegistration;
use Nucleos\UserBundle\Model\User as BaseUser;
class Registration extends BaseRegistration
class User extends BaseUser
{
/**
* @var bool|null
*/
protected $termsAccepted;
/**
* @return bool|null
*/
protected ?bool $termsAccepted = false;
public function gettermsAccepted(): ?bool
{
return $this->termsAccepted;
}
/**
* @param Boolean|null $termsAccepted
*/
public function setTermsAccepted(?bool $termsAccepted): void
{
$this->termsAccepted = $termsAccepted;
}
}
2. Add custom form model to configuration

.. code-block:: yaml
nucleos_profile:
registration:
form:
model: App\Form\Model\Registration
3. Use Symfony Form Extensions to add fields. You can use builder to remove or modify fields as well.
2. Use Symfony Form Extensions to add fields. You can use builder to remove or modify fields as well.

.. code-block:: php-annotations
Expand All @@ -68,7 +45,6 @@ If you want to modify the Registration form in your project there are a few step
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Adding new fields works just like in the parent form type.
$builder->add('termsAccepted', CheckboxType::class);
}
Expand Down
5 changes: 0 additions & 5 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -1,7 +1,2 @@
parameters:
ignoreErrors:
-
message: "#^Unsafe usage of new static\\(\\)\\.$#"
count: 1
path: src/Form/Model/Profile.php

64 changes: 21 additions & 43 deletions src/Action/EditProfileAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@

namespace Nucleos\ProfileBundle\Action;

use LogicException;
use Nucleos\ProfileBundle\Event\UserFormEvent;
use Nucleos\ProfileBundle\Form\Model\Profile;
use Nucleos\ProfileBundle\Form\Type\ProfileFormType;
use Nucleos\ProfileBundle\NucleosProfileEvents;
use Nucleos\UserBundle\Event\FilterUserResponseEvent;
Expand All @@ -22,6 +20,7 @@
use Nucleos\UserBundle\Model\UserManagerInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand All @@ -45,30 +44,20 @@ final class EditProfileAction

private Security $security;

/**
* @phpstan-var class-string<Profile>
*/
private string $formModel;

/**
* @phpstan-param class-string<Profile> $formModel
*/
public function __construct(
EventDispatcherInterface $eventDispatcher,
FormFactoryInterface $formFactory,
UserManagerInterface $userManager,
Environment $twig,
RouterInterface $router,
Security $security,
string $formModel
Security $security
) {
$this->eventDispatcher = $eventDispatcher;
$this->formFactory = $formFactory;
$this->userManager = $userManager;
$this->twig = $twig;
$this->router = $router;
$this->security = $security;
$this->formModel = $formModel;
}

public function __invoke(Request $request): Response
Expand All @@ -86,10 +75,8 @@ public function __invoke(Request $request): Response
return $event->getResponse();
}

$formModel = $this->createFormModel($user);

$form = $this->formFactory
->create(ProfileFormType::class, $formModel, [
$form = $this->formFactory
->create(ProfileFormType::class, $user, [
'validation_groups' => ['Profile', 'Default'],
])
->add('save', SubmitType::class, [
Expand All @@ -100,39 +87,30 @@ public function __invoke(Request $request): Response
$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
$formModel->updateUser($user);

$event = new UserFormEvent($user, $form, $request);
$this->eventDispatcher->dispatch($event, NucleosProfileEvents::PROFILE_EDIT_SUCCESS);
return $this->updateUser($request, $form, $user);
}

$this->userManager->updateUser($user);
return new Response($this->twig->render('@NucleosProfile/Profile/edit.html.twig', [
'form' => $form->createView(),
]));
}

if (null === $response = $event->getResponse()) {
$url = $this->router->generate('nucleos_profile_profile_show');
$response = new RedirectResponse($url);
}
private function updateUser(Request $request, FormInterface $form, UserInterface $user): Response
{
$event = new UserFormEvent($user, $form, $request);
$this->eventDispatcher->dispatch($event, NucleosProfileEvents::PROFILE_EDIT_SUCCESS);

$this->eventDispatcher->dispatch(
new FilterUserResponseEvent($user, $request, $response),
NucleosProfileEvents::PROFILE_EDIT_COMPLETED
);
$this->userManager->updateUser($user);

return $response;
if (null === $response = $event->getResponse()) {
$response = new RedirectResponse($this->router->generate('nucleos_profile_profile_show'));
}

return new Response(
$this->twig->render('@NucleosProfile/Profile/edit.html.twig', [
'form' => $form->createView(),
])
$this->eventDispatcher->dispatch(
new FilterUserResponseEvent($user, $request, $response),
NucleosProfileEvents::PROFILE_EDIT_COMPLETED
);
}

private function createFormModel(UserInterface $user): Profile
{
if (!is_a($this->formModel, Profile::class, true)) {
throw new LogicException(sprintf('The "%s" is not a valid "%s" class', $this->formModel, Profile::class));
}

return ($this->formModel)::fromUser($user);
return $response;
}
}
36 changes: 9 additions & 27 deletions src/Action/RegistrationAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@

use Nucleos\ProfileBundle\Event\GetResponseRegistrationEvent;
use Nucleos\ProfileBundle\Event\UserFormEvent;
use Nucleos\ProfileBundle\Form\Model\Registration;
use Nucleos\ProfileBundle\Form\Type\RegistrationFormType;
use Nucleos\ProfileBundle\NucleosProfileEvents;
use Nucleos\UserBundle\Event\FilterUserResponseEvent;
use Nucleos\UserBundle\Event\FormEvent;
use Nucleos\UserBundle\Model\UserInterface;
use Nucleos\UserBundle\Model\UserManagerInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormFactoryInterface;
Expand All @@ -41,43 +41,33 @@ final class RegistrationAction

private RouterInterface $router;

/**
* @phpstan-var class-string<Registration>
*/
private string $formModel;

/**
* @phpstan-param class-string<Registration> $formModel
*/
public function __construct(
EventDispatcherInterface $eventDispatcher,
FormFactoryInterface $formFactory,
UserManagerInterface $userManager,
RouterInterface $router,
Environment $twig,
string $formModel
Environment $twig
) {
$this->eventDispatcher = $eventDispatcher;
$this->formFactory = $formFactory;
$this->userManager = $userManager;
$this->router = $router;
$this->twig = $twig;
$this->formModel = $formModel;
}

public function __invoke(Request $request): Response
{
$formModel = $this->createFormModel();
$user = $this->userManager->createUser();

$event = new GetResponseRegistrationEvent($formModel, $request);
$event = new GetResponseRegistrationEvent($user, $request);
$this->eventDispatcher->dispatch($event, NucleosProfileEvents::REGISTRATION_INITIALIZE);

if (null !== $event->getResponse()) {
return $event->getResponse();
}

$form = $this->formFactory
->create(RegistrationFormType::class, $formModel, [
$form = $this->formFactory
->create(RegistrationFormType::class, $user, [
'validation_groups' => ['Registration', 'Default'],
])
->add('save', SubmitType::class, [
Expand All @@ -89,7 +79,7 @@ public function __invoke(Request $request): Response

if ($form->isSubmitted()) {
if ($form->isValid()) {
return $this->updateUser($request, $formModel, $form);
return $this->updateUser($request, $user, $form);
}

$event = new FormEvent($form, $request);
Expand All @@ -105,23 +95,15 @@ public function __invoke(Request $request): Response
]));
}

private function createFormModel(): Registration
private function updateUser(Request $request, UserInterface $user, FormInterface $form): Response
{
return new $this->formModel();
}

private function updateUser(Request $request, Registration $formModel, FormInterface $form): Response
{
$user = $formModel->toUser($this->userManager);

$event = new UserFormEvent($user, $form, $request);
$this->eventDispatcher->dispatch($event, NucleosProfileEvents::REGISTRATION_SUCCESS);

$this->userManager->updateUser($user);

if (null === $response = $event->getResponse()) {
$url = $this->router->generate('nucleos_profile_registration_confirmed');
$response = new RedirectResponse($url);
$response = new RedirectResponse($this->router->generate('nucleos_profile_registration_confirmed'));
}

$this->eventDispatcher->dispatch(
Expand Down
Loading

0 comments on commit 7ae0454

Please sign in to comment.