2

これは私の元の質問からのフォローアップの質問です: symfony2 で mysql 列挙型を教義エンティティに移行するための最良の戦略?

ここの指示に従って enum データ型を追加することに成功しました : http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/cookbook/mysql-enums.htmlベースEnumTypeクラスを作成し、それを次のように拡張する後半部分を使用したソリューション2:

<?php
namespace CP\AdminBundle\DataTypes;

class EnumContactBasicGender extends EnumType
{
    protected $name = 'EnumContactBasicGender';
    protected $values = array('m','f');

}

私の EnumType クラスは次のようになります。

<?php
namespace CP\AdminBundle\DataTypes;

use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;

abstract class EnumType extends Type
{
    protected $name;
    protected $values = array();

    public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
    {
        $values = array_map(function($val) { return "'".$val."'"; }, $this->values);

        return "ENUM(".implode(", ", $values).") COMMENT '(DC2Type:".$this->name.")'";
    }

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        return $value;
    }

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        if (!in_array($value, $this->values)) {
            throw new \InvalidArgumentException("Invalid enum value given: '".$this->value."' for enum: '".$this->name."'");
        }
        return $value;
    }

    public function getName()
    {
        return $this->name;
    }
}

そして、次のように列挙型を登録しました。

<?php

namespace CP\AdminBundle;
use Doctrine\DBAL\Types\Type;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class CPAdminBundle extends Bundle
{

 public function boot()
    {
        $em = $this->container->get('doctrine.orm.entity_manager');
        Type::addType('EnumContactBasicGender', 'CP\AdminBundle\DataTypes\EnumContactBasicGender');
        Type::addType('EnumContactBasicType', 'CP\AdminBundle\DataTypes\EnumContactBasicType');
        $em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('EnumContactBasicGender','EnumContactBasicGender');
        $em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('EnumContactBasicType','EnumContactBasicType');
    }
}

コマンド./app/console doctrine:generate:entities CPを実行すると動作します! 新しい列挙型データ型でエンティティを作成し、問題なくセッターとゲッターを作成します。私のエンティティの 1 つは次のようになります。

<?php
namespace CP\AdminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;


/**
 * CP\AdminBundle\Entity\ContactBasic
 *
 * @ORM\Table(name="contacts_basics")
 * @ORM\Entity(repositoryClass="CP\AdminBundle\Entity\ContactBasicRepository")
 */
class ContactBasic
{
    /** Field #1 (contacts_id) **/
    /**
    * @var integer $contacts_id
    * @ORM\Column(type="integer",nullable=false)
    * @ORM\Id
    * @ORM\GeneratedValue(strategy="AUTO")
    */
    private $contacts_id;
    /** enum ('m','f') **/
    /**
    * @ORM\Column(type="EnumContactBasicGender",nullable=false)
    */
    private $gender;
    /** enum ('non-customer','customer','blacklisted') **/
    /**
    * @ORM\Column(type="EnumContactBasicType",nullable=false)
    */
    private $type;

        /** more omitted properties here **/

    /**
     * Set gender
     *
     * @param EnumContactBasicGender $gender
     */
    public function setGender(\EnumContactBasicGender $gender)
    {
        $this->gender = $gender;
    }

    /**
     * Get gender
     *
     * @return EnumContactBasicGender 
     */
    public function getGender()
    {
        return $this->gender;
    }
    /**
     * Set type
     *
     * @param EnumContactBasicType $type
     */
    public function setType(\EnumContactBasicType $type)
    {
        $this->type = $type;
    }

    /**
     * Get type
     *
     * @return EnumContactBasicType 
     */
    public function getType()
    {
        return $this->type;
    }

        /** more omitted setters and getters here **/
}

私の問題は、フィクスチャ ローダーを作成するときに発生します。enum 値を設定してデータベースに保存する方法がわかりません。これまでのところ、フィクスチャ ローダー クラスは次のようになっています。

<?php
namespace CP\AdminBundle\DataFixtures\ORM;

use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use CP\AdminBundle\Entity\ContactBasic;
use CP\AdminBundle\DataTypes\EnumContactBasicGender;
use CP\AdminBundle\DataTypes\EnumContactBasicType;


class ContactBasicLoader implements FixtureInterface
{
    public function load(ObjectManager $manager)
    {


        $contact = new ContactBasic();
      //  $contact->setGender(new EnumContactBasicGender());
        $contact->setGender('m');

       // $contact->setType(new EnumContactBasicType());
        $contact->setType('customer');

        $manager->persist($contact);
        $manager->flush();




    }
}

./app/console doctrine:fixtures:loadを実行すると、次のエラーが表示されます。

Catchable Fatal Error: Argument 1 passed to CP\AdminBundle\Entity\ContactBasic::setGender() must be an instance of EnumContactBasicGender, string given

しかし、上記のコメント行のようにクラスを渡すと、エラーも発生します。

誰かが必要な値を設定する方法を説明してもらえますか?

4

2 に答える 2

1

Doctrine は列挙型を完全にはサポートしていません。列挙型はプロに見えますが、そのように列挙型を操作する人はいません。回避策は、整数値を持つエンティティにいくつかの静的変数を設定し、列挙型フィールドを整数型に設定することです。

あなたの問題で、性別のセッターを変更します:

  • メソッド パラメータなし 単純な文字列を入力して渡す
  • 文字列から列挙オブジェクトを作成します
  • enumObject をエンティティに割り当てます。

よろしく、マックス

于 2012-05-28T07:49:42.753 に答える
1

私は非常によく似た問題に直面しました.XXXEnumTypeクラスに値の同じ配列を追加することで解決しましたが、パブリックと静的です.

ただし、最初に、app/config/config.yml に my_foo_type を追加したかどうかを確認します。

# Doctrine Configuration
doctrine:
    dbal:
        driver:   %database_driver%
        host:     %database_host%
        port:     %database_port%
        dbname:   %database_name%
        user:     %database_user%
        password: %database_password%
        charset:  UTF8
        types:
          my_foo_type:      use XXX\DBAL\XXXEnumType
        mapping_types:
          enum: string

<?php
namespace XXX\DBAL;

class XXXEnumType extends EnumType
{
    protected $name = 'enum_xxx';
    protected $values = array('first', 'second', 'last');

    public static $static_name = 'enum_xxx';
    public static $static_values = array('first', 'second', 'last');

    public function getValues()
    {
        return $this->values;
    }
}

そして、私のプロジェクトの他の場所から私ができること:

use XXX\DBAL\XXXEnumType;

foreach (XXXEnumType::$static_values as $value)
{
    //do some stuff
}

それが役に立てば幸い、

Linuxatico

于 2012-05-29T13:26:39.053 に答える