Skip to content

Instantly share code, notes, and snippets.

@mikaelcom
Last active May 27, 2019 12:58
Show Gist options
  • Save mikaelcom/a057168da022c10645fc75b902324dbe to your computer and use it in GitHub Desktop.
Save mikaelcom/a057168da022c10645fc75b902324dbe to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
namespace App\Form;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Exception\InvalidArgumentException;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Form\FormBuilder as BaseFormBuilder;
use Symfony\Component\Form\FormFactoryInterface;
class FormBuilder extends BaseFormBuilder
{
private $innerName;
public function __construct(?string $name, ?string $dataClass, EventDispatcherInterface $dispatcher, FormFactoryInterface $factory, array $options = [])
{
parent::__construct(md5($name), $dataClass, $dispatcher, $factory, $options);
static::validateName($name);
$this->innerName = $name;
}
public function getName(): string
{
return $this->innerName;
}
/**
* Validates whether the given variable is a valid form name.
*
* @param string|int|null $name The tested form name
*
* @throws UnexpectedTypeException if the name is not a string or an integer
* @throws InvalidArgumentException if the name contains invalid characters
*/
public static function validateName($name)
{
if (null !== $name && !\is_string($name) && !\is_int($name)) {
throw new UnexpectedTypeException($name, 'string, integer or null');
}
if (!static::isValidName($name)) {
throw new InvalidArgumentException(sprintf('The name "%s" contains illegal characters. Names should start with a letter, digit or underscore and only contain letters, digits, numbers, underscores ("_"), hyphens ("-") and colons (":").', $name));
}
}
public static function isValidName($name)
{
return '' === $name || null === $name || preg_match('/^[\p{L}\p{N}_][\p{L}\p{N}_\-:]*$/Du', $name);
}
}
<?php
declare(strict_types=1);
namespace App\Form;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Form\ButtonTypeInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\SubmitButtonTypeInterface;
use Symfony\Component\Form\ResolvedFormType as BaseResolvedFormType;
class ResolvedFormType extends BaseResolvedFormType
{
public function newBuilder($name, $dataClass, FormFactoryInterface $factory, array $options)
{
if ($this->getInnerType() instanceof ButtonTypeInterface || $this->getInnerType() instanceof SubmitButtonTypeInterface) {
return parent::newBuilder($name, $dataClass, $factory, $options);
}
return new FormBuilder($name, $dataClass, new EventDispatcher(), $factory, $options);
}
}
<?php
declare(strict_types=1);
namespace App\Form;
use Symfony\Component\Form\ResolvedFormTypeFactoryInterface;
use Symfony\Component\Form\FormTypeInterface;
use Symfony\Component\Form\ResolvedFormTypeInterface;
class ResolvedFormTypeFactory implements ResolvedFormTypeFactoryInterface
{
/**
* @var ResolvedFormTypeFactoryInterface
*/
private $decorated;
public function __construct(ResolvedFormTypeFactoryInterface $decorated)
{
$this->decorated = $decorated;
}
/**
* {@inheritdoc}
*/
public function createResolvedType(FormTypeInterface $type, array $typeExtensions, ResolvedFormTypeInterface $parent = null)
{
return new ResolvedFormType($type, $typeExtensions, $parent);
}
public function __call($name, $arguments)
{
return call_user_func_array([
$this->decorated,
$name,
], $arguments);
}
}
services:
App\Form\ResolvedFormTypeFactory:
decorates: 'form.resolved_type_factory'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment