Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding related items using Sonata Admin and Propel

I have Sonata Admin up and running Using Propel with two models/Admin class defined; Portfolio and Image, where a portfolio item can have many images.

I have an ImageAdmin that allows for the images to be uploaded, associated with a portfolio item is required.
In the PortfolioAdmin I can add existing images to the portfolio item by using the model form mapper type.

Is there a way to add the ability to add/delete images when adding/editing a portfolio item, rather then just choose an existing one, or just a way to add/remove the related items not delete the image object as is the case for me at the moment.

I know I have the option of writing a custom Admin controller for the portfolio class, but is there a pre-built method of achieving this behaviour?

For reference, some code excerpts of what I have done;
Schema.xml

<database name="default" namespace="MyBundle\Model" defaultIdMethod="native">

    <table name="portfolio">
        <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
        <column name="title" type="varchar" primaryString="1" size="100" />
        <column name="description" type="LONGVARCHAR" />
        <behavior name="sluggable" />
        <behavior name="timestampable" />
        <behavior name="archivable" />
    </table>

    <table name="image">
        <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
        <column name="portfolio_id" type="integer" required="true" />
        <column name="title" type="varchar" primaryString="1" size="100" />
        <column name="path" type="varchar" size="255" />
        <column name="description" type="LONGVARCHAR" />
        <foreign-key foreignTable="portfolio">
            <reference local="portfolio_id" foreign="id"/>
        </foreign-key>
        <behavior name="sluggable" />
        <behavior name="timestampable" />
        <behavior name="archivable" />
    </table>

</database>

PortfolioAdmin.php

class PortfolioAdmin extends Admin
{

    protected $baseRouteName = 'portfolio';
    protected $baseRoutePattern = 'portfolio';

    // Fields to be shown on create/edit forms
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('title', 'text', array('label' => 'Title'))
            ->add('Images', 'model', array(
                    'class' => 'MyBundle\Model\Image',
                        'multiple' => true,
                        'expanded' => true, 
            ), array())
            ->add('description', 'text', array('label' => 'Description'))
        ;
    }
}

ImageAdmin.php

class ImageAdmin extends Admin
{

    protected $baseRouteName = 'image';
    protected $baseRoutePattern = 'image';

    // Fields to be shown on create/edit forms
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('title', 'text', array('label' => 'Title'))
            ->add('portfolio', 'sonata_type_model', array('label' => 'Job'))
            ->add('description', 'text', array('label' => 'Description'))
            ->add('file', 'file', array('required' => false))
        ;
    }
}

admin.yml

services:
    sonata.admin.portfolio:
        class: MyBundle\Admin\PortfolioAdmin
        tags:
            - { name: sonata.admin, manager_type: propel, group: "Content", label: "Portfolio" }
        arguments:
            - ~
            - MyBundle\Model\Portfolio
            - ~
        calls:
            - [ setTranslationDomain, [MyBundle]]
    sonata.admin.image:
        class: MyBundle\Admin\ImageAdmin
        tags:
            - { name: sonata.admin, manager_type: propel, group: "Images", label: "Portfolio Image" }
        arguments:
            - ~
            - MyBundle\Model\Image
            - ~
        calls:
            - [ setTranslationDomain, [MyBundle]]
like image 866
Rooneyl Avatar asked Nov 07 '14 13:11

Rooneyl


1 Answers

You could use the plain old collection field type.

Given the following ImageType:

class ImageType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('title', 'text');
        $builder->add('description', 'textarea');
        $builder->add('file', 'file', array('required' => false));
    }

    public function getName()
    {
        return 'image';
    }
}

The PortfolioAdmin class becomes:

class PortfolioAdmin extends Admin
{
    protected $baseRouteName = 'portfolio';
    protected $baseRoutePattern = 'portfolio';

    // Fields to be shown on create/edit forms
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('title', 'text', array('label' => 'Title'))
            ->add('images', 'collection', array(
                'type'         => new ImageType(),
                'by_reference' => false,
                'allow_add'    => true,
                'allow_delete' => true,
            ))
            ->add('description', 'text', array('label' => 'Description'))
        ;
    }
}
like image 123
K-Phoen Avatar answered Sep 24 '22 01:09

K-Phoen