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

Posted

技术标签:

【中文标题】集成 Sonata Media Bundle(媒体实体)和 Sonata Classiffication Bundle(标签实体)【英文标题】:Integrate Sonata Media Bundle (Media Entity) and Sonata Classiffication Bundle (Tags Entity) 【发布时间】:2016-04-24 06:33:00 【问题描述】:

我需要整合这两个包,以便能够添加标签到媒体实体(图像、视频等)。

我正在使用:

“奏鸣曲项目/媒体包”:“版本”:“2.3.1” “奏鸣曲项目/分类捆绑”:“版本”:“2.2.1” "symfony/symfony":"version": "v2.4.10"

【问题讨论】:

您是否也打算通过管理包管理这些? 是的,我这样做...所以,当我上传图片时,我可以在上面附加额外的信息。 【参考方案1】:

在奏鸣曲沙箱中,它们演示了覆盖实体。

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

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

您可以向位于here 的媒体实体添加额外的属性

AppBundle\Entity\Media\Media.php

 /**
 * @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 的原则 xml 以包含这些新关系

AppBundle\Resources\config\doctrine\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 为每个存储模型 ORM|ODM|phpCR 都有一个管理类,实现抽象类 BaseMediaAdmin 不幸的是,我们必须扩展每一个使用。我相信 ORM 是最常见的,所以我们将扩展 that one

我们要做的是为标签添加一个表单域

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

AppBundle\Admin\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\Compiler\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,但这应该是您开始所需的一切。

【讨论】:

谢谢....我会试试这个...这对我很有帮助。我之前没有使用过 OverrideServiceCompilerPass,这是一个很好的方法 只是我选择的类名。你可以使用任何你喜欢的名字 谢谢@StrikeForceZero 这对我有用。我搜索了这个解决方案一周。最后我从你的回答中得到了它。非常感谢!!!

以上是关于集成 Sonata Media Bundle(媒体实体)和 Sonata Classiffication Bundle(标签实体)的主要内容,如果未能解决你的问题,请参考以下文章

Symfony Sonata Media Bundle 向用户添加图像/视频

Sonata Media Bundle 安装错误

如何在 Sonata Media Bundle 中实现多对多关系

Symfony2 Sonata Media Bundle -- 上传图片时出错

Sonata media bundle 如何启用 pixlr 编辑?

Sonata Media Bundle Custom Provider 未映射请求数据