集成 Sonata Media Bundle(媒体实体)和 Sonata Classification Bundle(标签实体)
Integrate Sonata Media Bundle (Media Entity) and Sonata Classiffication Bundle (Tags Entity)
我需要整合这两个包才能添加标签到媒体实体(图像、视频等) .
我正在使用:
"sonata-project/media-bundle":"version": "2.3.1"
"sonata-project/classification-bundle":"version": "2.2.1"
"symfony/symfony":"version":"v2.4.10"
在奏鸣曲沙箱中,他们演示了覆盖实体。
我建议查看他们的 appbundle 目录结构和配置。您可能必须使用当前的 2.3 分支文件夹布局,但概念是相同的。
下面的示例将假设您是 overriding/extending 每个实体。如果您只打算覆盖媒体实体,那么我相信您只需要将 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
的新联接 table,这是遵循现有模式并在 table 前加上 media__
和 media_tag
表示关系。
我们已经解决了扩展当前模式的部分。然后你需要告诉包使用你的class而不是here(这可能在你的app/config/config.yml
中而不是像沙盒app/config/sonata/sonata_media.yml
一样从app/config/sonata/sonata_media.yml
导入=33=]
sonata_media:
class:
media: AppBundle\Entity\Media\Media
最后一步是将 属性 添加到 MediaAdmin class 进行管理。这部分有点棘手,我不确定它是否是最理想的解决方案。
MediaBundle 有一个管理员 class 用于实现抽象 class 的每个存储模型 ORM|ODM|PHPCR
BaseMediaAdmin unfortunately we would have to extend each one used. I beleive ORM is the most common so we'll extend that one
我们要做的是为标签添加一个表单字段
所以在 AppBundle
中创建一个新目录 Admin
和一个名为 MediaAdmin
的 class(或者任何你喜欢的,只要它以 Admin 结尾)并扩展class 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));
}
然后我们需要添加编译器传递以使用我们的 class 覆盖 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
,但这应该是您入门所需的一切。
我需要整合这两个包才能添加标签到媒体实体(图像、视频等) .
我正在使用:
"sonata-project/media-bundle":"version": "2.3.1" "sonata-project/classification-bundle":"version": "2.2.1" "symfony/symfony":"version":"v2.4.10"
在奏鸣曲沙箱中,他们演示了覆盖实体。
我建议查看他们的 appbundle 目录结构和配置。您可能必须使用当前的 2.3 分支文件夹布局,但概念是相同的。
下面的示例将假设您是 overriding/extending 每个实体。如果您只打算覆盖媒体实体,那么我相信您只需要将 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
的新联接 table,这是遵循现有模式并在 table 前加上 media__
和 media_tag
表示关系。
我们已经解决了扩展当前模式的部分。然后你需要告诉包使用你的class而不是here(这可能在你的app/config/config.yml
中而不是像沙盒app/config/sonata/sonata_media.yml
一样从app/config/sonata/sonata_media.yml
导入=33=]
sonata_media:
class:
media: AppBundle\Entity\Media\Media
最后一步是将 属性 添加到 MediaAdmin class 进行管理。这部分有点棘手,我不确定它是否是最理想的解决方案。
MediaBundle 有一个管理员 class 用于实现抽象 class 的每个存储模型 ORM|ODM|PHPCR
BaseMediaAdmin unfortunately we would have to extend each one used. I beleive ORM is the most common so we'll extend that one
我们要做的是为标签添加一个表单字段
所以在 AppBundle
中创建一个新目录 Admin
和一个名为 MediaAdmin
的 class(或者任何你喜欢的,只要它以 Admin 结尾)并扩展class 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));
}
然后我们需要添加编译器传递以使用我们的 class 覆盖 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
,但这应该是您入门所需的一切。