Интеграция Sonata Media Bundle (Media Entity) и Sonata Classiffication Bundle (Tags Entity)

Мне нужно интегрировать эти два пакета, чтобы иметь возможность добавлять теги к объекту мультимедиа (изображению, видео и т. д.).

Я использую:

"sonata-project/media-bundle":"version": "2.3.1" "sonata-project/classification-bundle":"version": "2.2.1" "symfony/symfony":"версия": "v2.4.10"


person Denis Gimenez    schedule 18.01.2016    source источник
comment
Вы также планируете управлять ими через пакет администратора?   -  person StrikeForceZero    schedule 28.01.2016
comment
да, я знаю... поэтому, когда я загружаю изображение, я могу добавить к нему дополнительную информацию.   -  person Denis Gimenez    schedule 05.02.2016


Ответы (1)


В песочнице сонаты они демонстрируют превосходящие сущности.

Я бы предложил просмотреть их структуру каталогов и конфигурации appbundle. Возможно, вам придется использовать текущий макет папки ветки 2.3, но концепция та же.

в приведенных ниже примерах предполагается, что вы переопределяете/расширяете каждую сущность. Если вы планируете переопределить только объект мультимедиа, я считаю, что вам просто нужно изменить пространство имен для AppBundle\Entity\Classification\Tag на Sonata\ClassificationBundle\Model\Tag (не проверено)

вы можете добавить дополнительные свойства к объекту мультимедиа, расположенному здесь

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;
}

затем отредактируйте 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 указывает на взаимосвязь.

мы решили часть расширения текущей схемы. Затем вам нужно указать пакету использовать ваш класс, как показано здесь (это может быть в вашем 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 является наиболее распространенным, поэтому мы расширим это один

то, что мы хотим сделать, это добавить поле формы для тегов

поэтому создайте новый каталог Admin внутри AppBundle и класс с именем 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, но это должно быть все, что вам нужно для начала.

person StrikeForceZero    schedule 05.02.2016
comment
Спасибо .... я попробую это ... это мне очень помогает. Раньше я не использовал OverrideServiceCompilerPass, это отличный способ сделать это. - person Denis Gimenez; 10.02.2016
comment
Это просто название класса, которое я выбрал. Вы можете использовать любое имя, которое хотите - person StrikeForceZero; 10.02.2016
comment
Спасибо @StrikeForceZero У меня это работает. Я искал это решение в течение одной недели. Наконец я понял это из вашего ответа. Большое спасибо!!! - person Simbu Dev; 10.09.2019