我使用Symfony 2.8.3
我已阅读这些资源:
-
How to Create a Custom Form Field Type
-
Symfony2: Overriding a built-in field type with a custom field type having the same name
以及其中提到的其他一些。
有必要创建这样的“日期”字段类型,以满足客户的许多参数,包括格式。 这个字段类型(由我创建)必须在项目的任何地方使用,即使在其他包中也是如此。
我创建了一个类:
class DateType extends \Symfony\Component\Form\Extension\Core\Type\DateType {
// Here I overload the necessary methods
}
在服务中注册:
services:
#...
form.type.date:
class: Application\Symfony\Component\Form\Extension\Core\Type\DateType
tags:
- { name: form.type, alias: date }
#...
并以表格形式使用:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('birthday', 'date', array(
'widget' => 'single_text',
'label' => 'form.label.birthday',
'translation_domain' => $this->translation_domain,
'required' => true,
'invalid_message' => 'form.error.birthday',
'attr' => array(
'class' => 'datepicker without-error-text',
),
'format' => 'dd-MM-yyyy',
));
}
但是这段代码抛出异常:
字段类型“Symfony \ Component \ Form \ Extension \ Core \ Type \ DateType”未在服务容器中注册。
这是什么意思,'没有注册'?!!啊,是的,没有注册))。 那是因为我注册了我的字段类型而不是内置类型。
我上面展示的资源之一就如何强制注册客户类型提出了建议。
好的,我们来做吧。
我创建了一个自编译器:
namespace Acme\DemoBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class OverrideServiceCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$definition = $container->getDefinition('form.type.date');
$definition->setClass('Acme\DemoBundle\Form\Type\DateType');
}
}
在构建主包时使用它:
// src/Acme/DemoBundle/AcmeDemoBundle.php
namespace Acme\DemoBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Acme\DemoBundle\DependencyInjection\Compiler\OverrideServiceCompilerPass;
class AcmeDemoBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new OverrideServiceCompilerPass());
}
}
但它仍然不成功。该代码再次引发异常,但这次是不同的:
为服务“form.type.date”指定的类型名称与实际名称不匹配。 预期“Symfony \ Component \ Form \ Extension \ Core \ Type \ DateType”, 给定“Application \ Symfony \ Component \ Form \ Extension \ Core \ Type \ DateType”
在研究代码后,我发现Sonata项目抛出了异常 它的不同捆绑。在我的项目中,我使用了Sonata Admin和Sonata Blocks。这些捆绑包无法创建自定义 表单中的日期类型字段。因为他们收到了不同类别的名字。
//vendor\sonata-project\core-bundle\Form\Extension\DependencyInjectionExtension.php
// this block: if ($name !== get_class($type) && (method_exists($type, 'getName') && $type->getName() !== $name)) {...}
/**
* {@inheritdoc}
*/
public function getType($name)
{
// resolve code to FQCN
$name = self::findClass($this->mappingTypes, $name);
if (!isset($this->typeServiceIds[$name])) {
throw new InvalidArgumentException(sprintf('The field type "%s" is not registered with the service container.', $name));
}
$type = $this->container->get($this->typeServiceIds[$name]);
if ($name !== get_class($type) && (method_exists($type, 'getName') && $type->getName() !== $name)) {
throw new InvalidArgumentException(
sprintf('The type name specified for the service "%s" does not match the actual name. Expected "%s", given "%s"',
$this->typeServiceIds[$name],
$name,
get_class($type)
));
}
return $type;
}
现在告诉我,我做错了什么。
非常感谢。