集成Sonata Media Bundle(媒体实体)和Sonata Classiffication Bundle(标签实体)

时间:2016-01-18 23:03:44

标签: tags sonata symfony-2.4 sonata-media-bundle

我需要集成这两个捆绑才能添加标签到媒体实体(图片,视频等)。

我正在使用:

" sonata-project / media-bundle":" version":" 2.3.1" " sonata-project / classification-bundle":" version":" 2.2.1" " symfony / symfony":"版本":" v2.4.10"

1 个答案:

答案 0 :(得分:0)

在奏鸣曲沙箱中,他们演示了重写实体。

我建议查看他们的appbundle目录结构和配置。您可能必须使用当前的2.3分支文件夹布局,但概念是相同的。

以下示例假设您正在覆盖/扩展每个实体。如果您只打算覆盖媒体实体,那么我相信您只需要将AppBundle\Entity\Classification\Tag的命名空间更改为Sonata\ClassificationBundle\Model\Tag(未测试)

您可以向位于here

的媒体实体添加额外的属性

<强>的appbundle \实体\媒体\忽略原始

 /**
 * @var ArrayCollection|\AppBundle\Entity\Classification\Tag[]
 */
protected $tags;

/**
 * {@inheritdoc}
 */
public function __construct()
{
    parent::__construct();
    $this->tags           = new ArrayCollection();
}

/**
 * @return ArrayCollection|\AppBundle\Entity\Classification\Tag[]
 */
public function getTags()
{
    return $this->tags;
}

/**
 * @param ArrayCollection|\AppBundle\Entity\Classification\Tag[] $tags
 */
public function setTags($tags)
{
    $this->tags = $tags;
}

然后编辑位于here的doctrine xml以包含这些新关系

<强>的appbundle \资源\配置\教义\ Media.Media.orm.xml

<many-to-many field="tags" target-entity="\AppBundle\Entity\Classification\Tag">
        <cascade>
            <cascade-persist/>
        </cascade>
        <join-table name="media__media_tag">
            <join-columns>
                <join-column name="media_id" referenced-column-name="id" nullable="false" unique="false" />
            </join-columns>
            <inverse-join-columns>
                <join-column name="tag_id" referenced-column-name="id" column-definition="INT NULL" />
            </inverse-join-columns>
        </join-table>
    </many-to-many>

请注意我们正在创建一个名为media__media_tag的新联接表,这是遵循现有模式,并在表格前加上media__media_tag表示关系。

我们已经解决了扩展当前架构的问题。然后,您需要告诉捆绑包使用您的类,而不是here(这可能在您的app/config/config.yml中,而不是像沙箱那样从app/config/sonata/sonata_media.yml导入

sonata_media:
class:
    media:             AppBundle\Entity\Media\Media

最后一步是将属性添加到MediaAdmin类进行管理。这部分有点棘手,我不确定它是否是最理想的解决方案。

MediaBundle为实现抽象类BaseMediaAdmin的每个存储模型ORM|ODM|PHPCR都有一个管理类,遗憾的是我们必须扩展每个使用的。我相信ORM是最常见的,所以我们会扩展that one

我们要做的是为标签添加表单字段

所以在Admin内创建一个新目录AppBundle和一个名为MediaAdmin的类(或任何你喜欢的,只要它在Admin中结束)并扩展类Sonata\MediaBundle\Admin\ORM\MediaAdmin 。下面的示例我们覆盖configureFormFields并在添加标记字段之前调用父项。

<强>的appbundle \管理员\ MediaAdmin.php

namespace AppBundle\Admin;

class MediaAdmin extends \Sonata\MediaBundle\Admin\ORM
{

    /**
     * {@inheritdoc}
     */
    protected function configureFormFields(FormMapper $formMapper)
    {
        parent::configureFormFields($formMapper);

        $formMapper->add('tags', 'sonata_type_model', array('multiple' => true, 'by_reference' => false));
    }

然后我们需要添加一个编译器传递来覆盖我们类的MediaAdmin服务。

<强>的appbundle \ AppBundle.php

namespace AppBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use AppBundle\DependencyInjection\Compiler\OverrideServiceCompilerPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class AppBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        parent::build($container);

        $container->addCompilerPass(new OverrideServiceCompilerPass());
    }
}

<强>的appbundle \ DependencyInjection \编译\ OverrideServiceCompilerPass.php

namespace AppBundle\DependencyInjection\Compiler;

use AppBundle\Admin\MediaAdmin;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

class OverrideServiceCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $definition = $container->getDefinition('sonata.media.admin.media');
        $definition->setClass(MediaAdmin::class);
    }
}

如果您想添加标记过滤器,可以覆盖configureDatagridFilters,但这应该是让您入门所需的一切。