首页 文章

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

提问于
浏览
0

我需要 integrate this two bundles 能够 add Tags 到媒体实体(图像,视频等) .

I'm using:

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

1 回答

  • 0

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

    我建议查看他们的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的doctrine 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 ,但这应该是让你入门所需的一切 .

相关问题