简体   繁体   中英

How embed fields of an other entity in sonata form?

I have two entities Sport and Tarif (translated by price) linked by ManyToOne relation.

I would like to have just one admin form (in Sonata Admin Bundle) to create or delete a Sport with three fields :

  • libelle ( = name)
  • valeurDeBase ( = price value) which is a number attribute of Tarif entity
  • conditionDeReduction ( = condition to have a discount) which is a text attribute of Tarif entity

I'm searching a way to do that and I found the use of CollectionType ( https://sonata-project.org/bundles/doctrine-orm-admin/master/doc/reference/form_field_definition.html ) to embed the Tarif fields in SportAdmin form but that's not working as you can see below :

SportAdmin表单的屏幕截图

Here are the entities :

Sport.php

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* Sport
*
* @ORM\Table(name="sport")
* @ORM\Entity(repositoryClass="AppBundle\Repository\SportRepository")
*/
class Sport
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="libelle", type="string", length=255, unique=true)
 */
private $libelle;

/**
 * Un Sport est lié à 1 et 1 seul Tarif
 * @ORM\ManyToOne(targetEntity="Tarif")
 * @ORM\JoinColumn(nullable=false)
 */
private $tarif;


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

/**
 * Set libelle
 *
 * @param string $libelle
 * @return Sport
 */
public function setLibelle($libelle)
{
    $this->libelle = $libelle;

    return $this;
}

/**
 * Get libelle
 *
 * @return string 
 */
public function getLibelle()
{
    return $this->libelle;
}
/**
 * Constructor
 */
public function __construct()
{
    $this->licences = new \Doctrine\Common\Collections\ArrayCollection();
}

/**
 * Add licence
 *
 * @param \AppBundle\Entity\Licence $licence
 *
 * @return Sport
 */
public function addLicence(\AppBundle\Entity\Licence $licence)
{
    $this->licences[] = $licence;

    return $this;
}

/**
 * Remove licence
 *
 * @param \AppBundle\Entity\Licence $licence
 */
public function removeLicence(\AppBundle\Entity\Licence $licence)
{
    $this->licences->removeElement($licence);
}

/**
 * Get licences
 *
 * @return \Doctrine\Common\Collections\Collection
 */
public function getLicences()
{
    return $this->licences;
}

/**
 * Set tarif
 *
 * @param \AppBundle\Entity\Tarif $tarif
 *
 * @return Sport
 */
public function setTarif(\AppBundle\Entity\Tarif $tarif)
{
    $this->tarif = $tarif;

    return $this;
}

/**
 * Get tarif
 *
 * @return \AppBundle\Entity\Tarif
 */
public function getTarif()
{
    return $this->tarif;
}
}

Tarif.php

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* Tarif
*
* @ORM\Table(name="tarif")
* @ORM\Entity(repositoryClass="AppBundle\Repository\TarifRepository")
*/
class Tarif
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="valeurDeBase", type="decimal", precision=10, scale=2)
 */
private $valeurDeBase;

/**
 * @var string
 *
 * @ORM\Column(name="conditionReduction", type="text", nullable=true)
 */
private $conditionReduction;

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

/**
 * Set valeurDeBase
 *
 * @param string $valeurDeBase
 * @return Tarif
 */
public function setValeurDeBase($valeurDeBase)
{
    $this->valeurDeBase = $valeurDeBase;

    return $this;
}

/**
 * Get valeurDeBase
 *
 * @return string 
 */
public function getValeurDeBase()
{
    return $this->valeurDeBase;
}

/**
 * Set conditionReduction
 *
 * @param string $conditionReduction
 * @return Tarif
 */
public function setConditionReduction($conditionReduction)
{
    $this->conditionReduction = $conditionReduction;

    return $this;
}

/**
 * Get conditionReduction
 *
 * @return string 
 */
public function getConditionReduction()
{
    return $this->conditionReduction;
}
}

SportAdmin.php

<?php

// src/AppBundle/Admin/SportAdmin.php
namespace AppBundle\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\CoreBundle\Form\Type\CollectionType;

class SportAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper->add('libelle', 'text');
    $formMapper->add('tarif', CollectionType::class, array(
        'by_reference' => false
    ),
    array(
        'edit' => 'inline',
        'inline' => 'table',
        'sortable' => 'position',
));
}

protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
    $datagridMapper->add('libelle');
}

protected function configureListFields(ListMapper $listMapper)
{
    $listMapper->addIdentifier('id');
    $listMapper->add('libelle');
    $listMapper->add('tarif.valeurDeBase');
    $listMapper->add('tarif.conditionReduction');
}

public function toString($object)
{
    return $object instanceof Sport
        ? $object->getTitle()
        : 'Sport'; // shown in the breadcrumb on the create view
}
}

TarifAdmin.php

<?php

// src/AppBundle/Admin/TarifAdmin.php
namespace AppBundle\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;

class TarifAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper->add('valeurDeBase', 'number');
    $formMapper->add('conditionReduction', 'text');
}

protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{

}

protected function configureListFields(ListMapper $listMapper)
{

}

public function toString($object)
{
    return $object instanceof Tarif
        ? $object->getTitle()
        : 'Tarif'; // shown in the breadcrumb on the create view
}
}

Thank you for your help.

Finally I have created an admin block for Tarif and embed it in SportAdmin with sonata_type_admin. It works perfectly. Here the SportAdmin.php

<?php

// src/AppBundle/Admin/SportAdmin.php
namespace AppBundle\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\CoreBundle\Form\Type\CollectionType;

class SportAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper->add('libelle', 'text');
    $formMapper->add('tarif', 'sonata_type_admin', array(), array(
        'admin_code' => 'admin.tarif'
    ));
}

protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
    $datagridMapper->add('libelle');
}

protected function configureListFields(ListMapper $listMapper)
{
    $listMapper->addIdentifier('id');
    $listMapper->add('libelle');
    $listMapper->add('tarif.valeurDeBase');
    $listMapper->add('tarif.conditionReduction');
}

public function toString($object)
{
    return $object instanceof Sport
        ? $object->getTitle()
        : 'Sport'; // shown in the breadcrumb on the create view
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM