我正在研究symfony2的crud bundle generator。
我创建了一个新的自定义表单字段权限richtext,我可以在我的表单中使用它,如:
$builder->('myField', 'richtext');
它正在工作,我还创建了一个自定义映射类型:
在我的实体中,我可以使用:
/**
* @var string
*
* @ORM\Column(name="lastComment", type="richtext", nullable=true)
*/
private $lastComment;
config.yml
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
# find custom mapping
types:
richtext: Acme\CrudBundle\Entity\Type\RichtextType
mapping_types:
richtext: text
RichtextType.php
<?php
namespace Acme\CrudBundle\Entity\Type;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* Richtext datatype.
*/
class RichtextType extends Type
{
const RICHTEXT = 'richtext'; // modify to match your type name
public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return 'richtext';
}
public function canRequireSQLConversion()
{
return false;
}
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return (is_resource($value)) ? stream_get_contents($value) : $value;
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return $value->toDecimal();
}
public function getName()
{
return self::RICHTEXT;
}
}
看起来不错。
当我使用命令生成表单时:
php app/console generate:doctrine:form
在我的表格中我有:
$builder->add('lastComment');
但是symfony创建了一个:
<input type="text"/>
如何覆盖symfony字段类型猜测以生成自定义字段Richtext?
回答:
好的,rtfm ...当我使用
时,Symfony会尝试猜测表单字段类型$builder->add('lastcomment');
所以我构建了一个自定义猜测器,但我需要像这样注入ManagerRegistry:
rudbundle.form.guesser.richtext:
class: Acme\CrudBundle\Form\Bridge\CustomTypeGuesser
arguments: ["@doctrine"]
tags:
- { name: form.type_guesser, alias: richtext_guesser }
CustomTypeGuesser.php
<?php
namespace Acme\CrudBundle\Form\Bridge;
use Symfony\Component\Form\FormTypeGuesserInterface;
use Symfony\Bridge\Doctrine\Form\DoctrineOrmTypeGuesser;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\ORM\EntityManager;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\Common\Persistence\Mapping\MappingException;
use Doctrine\ORM\Mapping\MappingException as LegacyMappingException;
use Symfony\Component\Form\Guess\Guess;
use Symfony\Component\Form\Guess\TypeGuess;
use Symfony\Component\Form\Guess\ValueGuess;
class CustomTypeGuesser implements FormTypeGuesserInterface
{
protected $em;
protected $registry;
private $cache = array();
public function __construct(ManagerRegistry $managerRegistry){
$this->registry = $managerRegistry;
// $this->registry = $registry;
}
public function guessType($class, $property)
{
if (!$ret = $this->getMetadata($class)) {
return;
}
list($metadata, $name) = $ret;
if ($metadata->hasAssociation($property)) {
return;
}
if( $metadata->getTypeOfField($property) == 'richtext' )
return new TypeGuess('richtext', array(), Guess::HIGH_CONFIDENCE);
}
public function guessRequired($class, $property)
{
}
public function guessMaxLength($class, $property)
{
}
public function guessPattern($class, $property)
{
}
// public function getMetadata($class)
// {
// return $this->getEntityManager($class)->getMetadataFactory()->getMetadataFor($class);
// }
protected function getMetadata($class)
{
// normalize class name
$class = ClassUtils::getRealClass(ltrim($class, '\\'));
if (array_key_exists($class, $this->cache)) {
return $this->cache[$class];
}
$this->cache[$class] = null;
foreach ($this->registry->getManagers() as $name => $em) {
try {
return $this->cache[$class] = array($em->getClassMetadata($class), $name);
} catch (MappingException $e) {
// not an entity or mapped super class
} catch (LegacyMappingException $e) {
// not an entity or mapped super class, using Doctrine ORM 2.2
}
}
}
}