Skip to content

Instantly share code, notes, and snippets.

@chrisguitarguy
Created February 22, 2016 21:30
Show Gist options
  • Save chrisguitarguy/47fcecc00be0aa8713f0 to your computer and use it in GitHub Desktop.
Save chrisguitarguy/47fcecc00be0aa8713f0 to your computer and use it in GitHub Desktop.
Keep your Symfony form's password value around if an empty value is submitted. Optionally supply a "Clear Password" field.
<?php
/**
* Copyright (c) 2016 PMG <https://www.pmg.com>
*
* License: MIT
*/
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Use inside your form types.
*
* public function buildForm(FormBuilderInterface $build, array $options)
* {
* $build->add('password', PasswordType::class);
* $build->add('remove_password', CheckboxType::class, [
* 'mapped' => false,
* ]);
* $build->addEventSubscriber(new KeepPasswordListener('password', 'remove_password'));
* }
*/
final class KeepPasswordListener implements EventSubscriberInterface
{
/**
* The name of a password field whose value should be kept if an
* empty value is submitted.
*
* @var string
*/
private $passwordField;
/**
* The boolean (checkbox) field that tells the listener to clear
* the password.
*
* @var string
*/
private $clearField;
/**
* @var PropertyAccessorInterface
*/
private $accessor;
public function __construct($passwordField, $clearField=null, PropertyAccessorInterface $accessor=null)
{
$this->passwordField = $passwordField;
$this->clearField = $clearField;
$this->accessor = $accessor ?: PropertyAccess::createPropertyAccessor();
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return [
FormEvents::PRE_SUBMIT => 'maybeKeepPassword',
];
}
public function maybeKeepPassword(FormEvent $event)
{
$pwField = $event->getForm()->get($this->passwordField);
$formData = $event->getForm()->getData();
$submitData = $event->getData();
$erasePassword = false;
if ($this->clearField && isset($submitData[$this->clearField])) {
$erasePassword = self::asBool($submitData[$this->clearField]);
}
// if we're erasing the password we can get out of here straight away
if ($erasePassword) {
$submitData[$this->passwordField] = $pwField->getConfig()->getEmptyData();
$event->setData($submitData);
return;
}
if (empty($submitData[$this->passwordField])) {
$submitData[$this->passwordField] = $this->accessor->getValue(
$event->getForm()->getData(),
$pwField->getPropertyPath()
);
$event->setData($submitData);
}
}
private static function asBool($value)
{
return filter_var($value, FILTER_VALIDATE_BOOLEAN);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment