priktop
priktop

Reputation: 1155

Adding properties to/extending Sonata Media entity

I want to add properties to the Sonata Media entity, but I just can't get it to work. I'm using Sonata Media Bundle 2.3, and have installed it according to the manual. I also extended it with the Sonata Easy Extends Bundle.

When I add a property to Application\Sonata\MediaBundle\Entity\Media, it just doesn't get picked up when I run doctrine:generate:diff ('No changes detected in your mapping information.').

Overriding the media class in config.yml won't make a difference as well.

This is the code in Application\Sonata\MediaBundle\Entity\Media.php:

<?php

namespace Application\Sonata\MediaBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Sonata\MediaBundle\Entity\BaseMedia as BaseMedia;

/**
 * @ORM\Entity
 */
class Media extends BaseMedia
{
    /**
     * @var integer $id
     */
    protected $id;

    /**
     * @ORM\Column(type="string", nullable=true)
     */
    protected $test;

    /**
     * @return mixed
     */
    public function getTest()
    {
        return $this->test;
    }

    /**
     * @param mixed $test
     */
    public function setTest($test)
    {
        $this->test = $test;
    }

    /**
     * Get id
     *
     * @return integer $id
     */
    public function getId()
    {
        return $this->id;
    }
}

And in config.yml:

sonata_media:
    class:
        media: Application\Sonata\MediaBundle\Entity\Media
        gallery: Application\Sonata\MediaBundle\Entity\Gallery
        gallery_has_media: Application\Sonata\MediaBundle\Entity\GalleryHasMedia

Again, I get the same result if I leave that section commented out.

UPDATE: When I create a custom migration that adds the property, when I extend the MediaAdmin, the test field won't show up when I go to the image edit page:

// Application\Sonata\MediaBundle\Admin\MediaAdmin.php
<?php
namespace Sonata\MediaBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;

class MediaAdmin extends Admin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('name', null, ['required' => false])
            ->add('enabled', null, ['required' => false])
            ->add('authorName', null, ['required' => false])
            ->add('cdnIsFlushable', null, ['required' => false])
            ->add('description', null, ['required' => false])
            ->add('copyright', null, ['required' => false])
            ->add('test', null, ['required' => false])
            ->add('binaryContent', 'file', ['required' => false]);
    }
}

So it seems that Sonata is ignoring the extended Media Bundle (which isn't the case, because when I remove Application\Sonata\MediaBundle\Entity\Media.php, I get an error).

Upvotes: 0

Views: 2191

Answers (2)

Christophe Ferreboeuf
Christophe Ferreboeuf

Reputation: 1058

I needed to go throught the creation of different properties for the image and here is my solution using the default doctrine and the provider. I used easy-extends.

To add a property on Media without annotation, you can use the node <field name="url" type="string"/> to get something like in media.phpcr.xml :

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xsi="http://www.w3.org/2001/XMLSchema-instance" schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
    <!--
         This file has been generated by the EasyExtends bundle ( https://sonata-project.org/easy-extends )

         References :
            xsd                  : https://github.com/doctrine/doctrine2/blob/master/doctrine-mapping.xsd
            xml mapping          : http://www.doctrine-project.org/projects/orm/2.0/docs/reference/xml-mapping/en
            association mapping  : http://www.doctrine-project.org/projects/orm/2.0/docs/reference/association-mapping/en
    -->
    <entity
        name="Application\Sonata\MediaBundle\Entity\Media"
        table="media__media"
        >

        <id name="id" type="integer" column="id">
            <generator strategy="AUTO"/>
        </id>
        <field name="url" type="string"/>

    </entity>
</doctrine-mapping>

And then, without using annotation, you need to add in your extended Media.php :

<?php

namespace Application\Sonata\MediaBundle\Entity;

use Sonata\MediaBundle\Entity\BaseMedia as BaseMedia;

/**
 * This file has been generated by the Sonata EasyExtends bundle.
 *
 * @link https://sonata-project.org/bundles/easy-extends
 *
 * References :
 *   working with object : http://www.doctrine-project.org/projects/orm/2.0/docs/reference/working-with-objects/en
 *
 * @author Christophe Ferreboeuf <[email protected]>
 */
class Media extends BaseMedia
{
    /**
     * @var int $id
     */
    protected $id;

    /**
     * Permits to link the image to a different location on the website
     * @var string 
     */
    protected $url;

    /**
     * Get id
     *
     * @return int $id
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * 
     * @return string
     */
    public function getUrl() {
        return $this->url;
    }

    /**
     * 
     * @param string $url
     * @return \Application\Sonata\MediaBundle\Entity\Media
     */
    public function setUrl($url) {
        $this->url = $url;
        return $this;
    }


}

And declare it for ORM media.orm.xml :

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xsi="http://www.w3.org/2001/XMLSchema-instance" schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
    <!--
         This file has been generated by the EasyExtends bundle ( https://sonata-project.org/easy-extends )

         References :
            xsd                  : https://github.com/doctrine/doctrine2/blob/master/doctrine-mapping.xsd
            xml mapping          : http://www.doctrine-project.org/projects/orm/2.0/docs/reference/xml-mapping/en
            association mapping  : http://www.doctrine-project.org/projects/orm/2.0/docs/reference/association-mapping/en
    -->
    <entity
        name="Application\Sonata\MediaBundle\Entity\Media"
        table="media__media"
        >

        <id name="id" type="integer" column="id">
            <generator strategy="AUTO"/>
        </id>
        <field name="url" column="url" type="string" nullable="true" length="255"/>

    </entity>
</doctrine-mapping>

To by pass the problem with admin, you need to override the provider for image :

<?php
namespace Application\Sonata\MediaBundle\Provider;

use Sonata\MediaBundle\Provider\ImageProvider as BaseImageProvider;
use Sonata\AdminBundle\Form\FormMapper;
use Gaufrette\Filesystem;
use Imagine\Image\ImagineInterface;
use Sonata\CoreBundle\Model\Metadata;
use Sonata\MediaBundle\CDN\CDNInterface;
use Sonata\MediaBundle\Generator\GeneratorInterface;
use Sonata\MediaBundle\Metadata\MetadataBuilderInterface;
use Sonata\MediaBundle\Model\MediaInterface;
use Sonata\MediaBundle\Thumbnail\ThumbnailInterface;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Form\Form;

/**
 * Overrides the default provider to add the url field in the admin form
 *
 * @author christophe Ferreboeuf <[email protected]>
 */
class ImageProvider extends BaseImageProvider{

    /**
     * 
     * @param FormMapper $formMapper
     */
    public function buildCreateForm(FormMapper $formMapper)
    {
        $formMapper->add('binaryContent', array(), array('type' => 'string'));
    }

    /**
     * 
     * @param FormMapper $formMapper
     */
    public function buildEditForm(FormMapper $formMapper)
    {
        $formMapper->add('name');
        $formMapper->add('enabled');
        $formMapper->add('authorName');
        $formMapper->add('url');
        $formMapper->add('cdnIsFlushable');
        $formMapper->add('description');
        $formMapper->add('copyright');
        $formMapper->add(
            'binaryContent',
            // NEXT_MAJOR: Remove ternary and keep 'Symfony\Component\Form\Extension\Core\Type\FileType' value
            // (when requirement of Symfony is >= 2.8)
            method_exists('Symfony\Component\Form\AbstractType', 'getBlockPrefix')
                ? 'Symfony\Component\Form\Extension\Core\Type\FileType'
                : 'file',
            array('required' => false)
        );
    }
}

And declare it on your service (I prefer yml) :

sonata.media.provider.image:
     class: Application\Sonata\MediaBundle\Provider\ImageProvider
     arguments:
        - sonata.media.provider.image
        - @sonata.media.filesystem.local
        - @sonata.media.cdn.server
        - @sonata.media.generator.default
        - @sonata.media.thumbnail.format
        - []
        - []
        - @sonata.media.adapter.image.gd
        - @sonata.media.metadata.proxy
     tags:
        - { name: sonata.media.provider }
     calls:
        - [ setTemplates, [ { helper_thumbnail: SonataMediaBundle:Provider:thumbnail.html.twig, helper_view: SonataMediaBundle:Provider:view_image.html.twig } ] ]    

Upvotes: 1

priktop
priktop

Reputation: 1155

Well, it seems like I had to remove the Application/Sonata/MediaBundle/Resources/config/doctrine folder and annotate the Media entities as following:

<?php

namespace Application\Sonata\MediaBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Sonata\MediaBundle\Entity\BaseMedia as BaseMedia;

/**
 * @ORM\Table(name="media__media")
 * @ORM\Entity
 */
class Media extends BaseMedia

A simple php app/console doctrine:schema:update --force in the end did the trick. Hope this helps for those who encounter the same problem.

Upvotes: 1

Related Questions