默认情况下,Symfony2自定义表单类型和doctrine自定义映射

时间:2015-03-04 17:08:04

标签: forms symfony doctrine mapping

我正在研究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
        }
    }
}
}

0 个答案:

没有答案
相关问题