实现使用Symfony 2.8保持新实体的Doctrine类型

时间:2016-12-14 09:35:54

标签: php symfony doctrine entity

我有两个实体标记用户标记可以分为以下四种类别之一:运动食物音乐电影用户还有四个属性:运动食物音乐电影其中包含与类别相关的标签数组( user.sport 可以包含 sport 类别中的标签等)。

让我们看一点代码更清楚。

AcmeBundle /实体/ Tag.php

namespace AcmeBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Table(name="tag")
 * @ORM\Entity(repositoryClass="AcmeBundle\Repository\TagRepository")
 */
class Tag
{
    /**
     * @var int
     *
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     * 
     * @ORM\Column(name="category", type="string", length=255)
     */
    private $category;

    /**
     * @var string
     *
     * @ORM\Column(name="label", type="string", length=255)
     */
    private $label;
}

AcmeBundle /实体/ user.php的

namespace AcmeBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="AcmeBundle\Repository\UserRepository")
 */
class User extends BaseUser
{
    /**
     * @var int
     *
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var Tag[]
     *
     * @ORM\Column(name="sport", type="???")
     */
    private $sport;

    /**
     * @var Tag[]
     *
     * @ORM\Column(name="food", type="???")
     */
    private $food;

    /**
     * @var Tag[]
     *
     * @ORM\Column(name="music", type="???")
     */
    private $music;

    /**
     * @var Tag[]
     *
     * @ORM\Column(name="movie", type="???")
     */
    private $movie;
}

标签应该以这种形式存储在数据库中(数组以逗号作为分隔符进行内嵌)。

user_id | sport_tags | food_tags | music_tags | movie_tags
1       | 10,21,23   | 1,2,3     | 4,5        | 100

我想在持久用户期间自动保留标签。请看下面的例子。

$manager = $this->getDoctrine()->getManager();

$user = $manager->getRepository('AcmeBundle:User')->find(1);

$tag1 = $manager->getRepository('AcmeBundle:Tag')->find(10);
$tag2 = $manager->getRepository('AcmeBundle:Tag')->find(21);
$tag3 = $manager->getRepository('AcmeBundle:Tag')->find(23);

$tag4 = new Tag();
$tag4->setLabel('New tag');
$tag4->setCategory('sport');

$user->setSport(array(
    $tag1,
    $tag2,
    $tag3,
    $tag4,
));

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

从数据库中获取用户后,标签的ID应自动转换为标签。从下面的示例转储应返回标记数组。

$manager = $this->getDoctrine()->getManager();
$user = $manager->getRepository('AcmeBundle:User')->find(1);
var_dump($user->getSport());

但我不确定如何实现这一点。我实现了新的Doctrine类型,它将标签数组转换为字符串(例如“10,21,23”),反之亦然。但是如何自动保留新标签?如果我试图在convertToDatabaseValue中保留标记,那么它不起作用(服务器关闭)。请参阅下面的我的TagType实现。

namespace AcmeBundle\Types;

use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManager;
use AcmeBundle\Entity\Tag;

class TagType extends Type
{
    /**
     * @var EntityManager
     */
    private $manager;

    /**
     * @return string
     */
    public function getName()
    {
        return 'TagType';
    }

    /**
     * @param EntityManager $manager
     */
    public function setEntityManager(EntityManager $manager)
    {
        $this->manager = $manager;
    }

    /**
     * @param array $fieldDeclaration
     * @param AbstractPlatform $platform
     * @return string
     */
    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
    {
        if ($fieldDeclaration['notnull']) {
            return 'LONGTEXT NOT NULL';
        } else {
            return 'LONGTEXT';
        }
    }

    /**
     * @param mixed $value
     * @param AbstractPlatform $platform
     * @return array
     */
    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        if ($value === null) {
            return array();
        } else {
            return array_filter(array_map(function ($id) {
                return $this->manager->getRepository('AcmeBundle:Tag')->find($id);
            }, explode(',', $value)));
        }
    }

    /**
     * @param mixed $value
     * @param AbstractPlatform $platform
     * @return string
     */
    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        if ($value === null) {
            return '';
        } else {
            return implode(',', array_filter(array_map(function (Tag $tag) {
                try {
                    return $tag->getId();
                } catch (\Exception $exception) {
                    return null;
                }
            }, $value)));
        }
    }
}

0 个答案:

没有答案