Here I am on a project for my studies and I use symfony fosUser and sonata, I have a Book entity that I administer with sonata.
The problem is that I want to give an user to a book, but it becomes complicated when I want to find in my field user only the user whose role ROLE_MyRole, I search on forums for several hours without finding.
I'm sorry for my incompetence I learn symfony recently and does not yet have enough experience.
This is my BookAdmin
class BookAdmin extends Admin
{
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
static $options = array();
$currentBook = $this->getSubject();
if (null !== $currentBook->getFileName())
$options = array(
'required' => false,
'help' => 'getWebPath().'">Download File : '.$currentBook->getFileName().'',
);
$formMapper
->add('title', null, array('label' => 'Titre : '))
->add('summary', null, array('label' => 'Résumé : '))
->add('category', null, array('label' => 'Catégorie : '))
->add('readers', null, array('label' => 'Lecteur(s) : '))
->add('file', 'file', $options)
;
}
And this is my Book entity with readers field
class Book
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
protected $title;
/**
* #var string
*
* #ORM\Column(name="summary", type="text")
*/
protected $summary;
/**
* #Assert\File(
* mimeTypes={"application/pdf", "application/x-pdf"},
* mimeTypesMessage="Only PDF"
* )
*/
protected $file;
/**
* #var string
*
* #ORM\Column(name="file_path", type="string", length=255)
*/
protected $fileName;
/**
* #var \DateTime
*
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="created_at", type="datetime")
*/
protected $createdAt;
/**
* #var \DateTime
*
* #Gedmo\Timestampable(on="update")
* #ORM\Column(name="updated_at", type="datetime")
*/
protected $updatedAt;
/**
* #var bool
*
* #ORM\Column(name="enabled", type="boolean", nullable=true)
*/
protected $enabled;
/**
* #var bool
*
* #ORM\Column(name="received_by_reader", type="boolean", nullable=true)
*/
protected $receivedByReader;
/**
* #var bool
*
* #ORM\Column(name="download_by_reader", type="boolean", nullable=true)
*/
protected $downloadByReader;
/**
* #var bool
*
* #ORM\Column(name="send_by_reader", type="boolean", nullable=true)
*/
protected $sendByReader;
/**
* #var bool
*
* #ORM\Column(name="reader_validation", type="boolean", nullable=true)
*/
protected $readerValidation;
/**
* #var bool
*
* #ORM\Column(name="edited", type="boolean", nullable=true)
*/
protected $edited;
/**
* #var User
*
* #ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\User")
*/
protected $author;
/**
* #var ArrayCollection
*
* #ORM\ManyToMany(targetEntity="Application\Sonata\UserBundle\Entity\User", cascade={"persist"})
*/
protected $readers;
Thanks You
You can do something like this in your admin class:
$formMapper
->add('readers', null, array(
'label' => 'Lecteur(s) : ',
'code' => 'getReadersWithMyRole'
))
and define in your User entity the following method:
/**
* Returns readers with "ROLE_MyRole" role
*
* #return array
*/
public function getReadersWithMyRole()
{
$result = array();
foreach ($this->getReaders() as $reader) {
if ($reader->hasRole('ROLE_MyRole')) {
$result[] = $reader;
}
}
return $result;
}
Hope it helps.
it doesn't work too but we have find a solution, we can do that like this :
->add('reader', null, array(
'class' => 'ApplicationSonataUserBundle:User',
'label' => 'Lecteur : ',
'query_builder' => function (EntityRepository $er) {
$qb = $er->createQueryBuilder('u');
$qb->where($qb->expr()->like('u.roles', $qb->expr()->literal('%ROLE_READER%')));
return $qb;
}))
if it can help someone
Related
I'm doing an AdvertPlatform with Symfony 2.5 and PHP 5.3.
I want to add a feature that is : when a user see(by clicking on it) an advert, we can see a text "Seen by : {{username}}".
I started add a new Entity nammed AdvertReader with a relation OneToMany between Advert and AdvertReader:
Advert.php:
/**
* Advert
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Society\PerfclientBundle\Entity\AdvertRepository")
* #ORM\HasLifecycleCallbacks()
* #UniqueEntity(fields="title", message="Une annonce existe déjà avec ce titre.")
*/
class Advert
{
public function __construct()
{
$this->date = new \Datetime();
}
/**
*
* #ORM\OneToMany(targetEntity="Society\PerfclientBundle\Entity\AdvertReader", mappedBy="advert", cascade={"persist"})
*/
private $readers;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \DateTime
*
* #ORM\Column(name="date", type="datetime")
*/
private $date;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255, unique=true)
*
* #Assert\Length(min=10, minMessage="Le titre de l'annonce doit faire au moins {{ limit }} caractères.")
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="category", type="string", length=255)
*/
private $category;
/**
* #var string
*
* #ORM\Column(name="author", type="string", length=255)
*/
private $author;
/**
* #var string
*
* #ORM\Column(name="content", type="text")
* #Assert\Length(min=10, minMessage="Le contenu de l'annonce doit faire au moins {{ limit }} caractères.")
*/
private $content;
/**
* #ORM\Column(name="updated_at", type="datetime", nullable=true)
*/
private $updatedAt;`
AdvertReader.php :
/**
* AdvertReader
*
* #ORM\Table()
* #ORM\Entity
*/
class AdvertReader
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Society\PerfclientBundle\Entity\Advert", inversedBy="readers")
* #ORM\JoinColumn(name="advert_id", referencedColumnName="id")
*/
private $advert;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=255)
*/
private $username;
/**
* #var \DateTime
*
* #ORM\Column(name="created_at", type="datetime")
*/
private $createdAt;
/**
* #var \DateTime
*
* #ORM\Column(name="updated_at", type="datetime")
*/
private $updatedAt;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set advert
*
* #param integer $advert
* #return AdvertReader
*/
public function setAdvert($advert)
{
$this->advert = $advert;
return $this;
}
/**
* Get advert
*
* #return integer
*/
public function getAdvert()
{
return $this->advert;
}
/**
* Set username
*
* #param string $username
* #return AdvertReader
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
And my viewAction()
/**
* #param $id
* #return Response
*/
public function viewAction($id)
{
// On récupère le repository
$repository = $this->getDoctrine()
->getManager()
->getRepository('SocietyPerfclientBundle:Advert')
;
$advert = $repository->find($id);
if (null === $advert) {
throw new NotFoundHttpException("L'annonce d'id ".$id." n'existe pas.");
}
$securityContext = $this->container->get('security.context');
$user = $securityContext->getToken()->getUser();
if ($securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
$em = $this->getDoctrine()->getManager();
$queryBuilder = $em->createQueryBuilder();
$query = $queryBuilder->select('count(ar.id)')
->from('SocietyPerfclientBundle:AdvertReader', 'ar')
->where('ar.advert = :advert')
->andWhere('ar.username = :username')
->setParameter('advert', $advert->getId())
->setParameter('username', $user->getUsername())
->getQuery();
$advertReaderCount = $query->getSingleScalarResult();
if ($advertReaderCount <= 0) {
// l'utilisateur lis pour la 1er fois
$advertReader = new AdvertReader;
$advertReader->setAdvert($advert->getId());
$advertReader->setUpdatedAt(new \DateTime);
$advertReader->setUsername($user->getUsername());
$advertReader->setCreatedAt(new \DateTime);
$em->persist($advertReader);
$em->flush();
}
}
return $this->render('SocietyPerfclientBundle:Default:view.html.twig', array(
'advert' => $advert,
));
}
doctrine:schema:validate -> [Mapping] OK [Database] OK
Error500 ORM Exception : Found entity of type on association Society\PerfclientBundle\Entity\AdvertReader#advert, but expecting Society\PerfclientBundle\Entity\Advert
Stack Trace Profiler :
UnitOfWork ->computeAssociationChanges (array('fieldName' => 'advert', 'joinColumns' => array(array('name' => 'advert_id', 'unique' => false, 'nullable' => true, 'onDelete' => null, 'columnDefinition' => null, 'referencedColumnName' => 'id')), 'cascade' => array(), 'inversedBy' => 'readers', 'targetEntity' => 'Society\PerfclientBundle\Entity\Advert', 'fetch' => '2', 'type' => '2', 'mappedBy' => null, 'isOwningSide' => true, 'sourceEntity' => 'Society\PerfclientBundle\Entity\AdvertReader', 'isCascadeRemove' => false, 'isCascadePersist' => false, 'isCascadeRefresh' => false, 'isCascadeMerge' => false, 'isCascadeDetach' => false, 'sourceToTargetKeyColumns' => array('advert_id' => 'id'), 'joinColumnFieldNames' => array('advert_id' => 'advert_id'), 'targetToSourceKeyColumns' => array('id' => 'advert_id'), 'orphanRemoval' => false), '26')
What's wrong with my entity relation ?
Please help me :)
I think the problem comes from this code piece of code
$advertReader->setAdvert($advert->getId());
Try this instead:
$advertReader->setAdvert($advert);
Doctrine is expecting an object on that relation and instead you pass some integer.
Hope this helps. Happy coding
Alexandru Cosoi
I have a form which save queries. This is organized in the way of a people who ask is saved also this create a threat where is saving the id_question and emailperson. The issue is that the same person does another question. Logically, this report a primary key error:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'drj00003#ujaen.es' for key 'PRIMARY'
How do I fix it? In the constructor of class I cannot check if this exists and all registers are generated automatically in cascade without form.
It should be easy but I can't solve this.
class HiloType extends AbstractType{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('consultanteemail', new ConsultanteType(), array ('label' => false))
->add('personalemail', 'entity', array(
'label' => 'Personal de Soporte',
'class' => 'GuiasDocentes\AppBundle\Entity\Personal',
'property' => 'Enunciado',
'by_reference' => 'false',
'query_builder' => function(PersonalRepository $pr) {
$query= $pr->createQueryBuilder('u')
;
return $query;
},
'empty_value' => 'Elige un perfil de consulta:',
))
;
}
...
class Hilo{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \GuiasDocentes\AppBundle\Entity\Personal
*
* #ORM\ManyToOne(targetEntity="Personal", inversedBy="hilos", cascade ={"ALL"})
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="personalEmail", referencedColumnName="email")
* })
*/
private $personalemail;
/**
* #var \GuiasDocentes\AppBundle\Entity\Consultante
*
* #ORM\ManyToOne(targetEntity="Consultante", inversedBy="hilos", cascade ={"ALL"} )
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="consultanteEmail", referencedColumnName="email")
* })
*/
private $consultanteemail;
/* Customized code */
/**
* #ORM\OneToMany(targetEntity="GuiasDocentes\AppBundle\Entity\Consulta", mappedBy="hiloid")
* #Assert\Valid()
*/
private $consultas;
public function __construct(){
$this->consultas = new ArrayCollection();
}
public function setConsultas (Consulta $consulta){
$this->hilos[]=$consulta;
}
public function addConsulta (\GuiasDocentes\AppBundle\Entity\Consulta $consulta){
$this->hilos[] = $consulta;
}
/* End customized code */
...
class Consultante{
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=50, nullable=false)
* #ORM\Id
*/
private $email;
/**
* #var string
*
* #ORM\Column(name="nombre", type="string", length=30, nullable=true)
*/
private $nombre;
/**
* #var string
*
* #ORM\Column(name="apellidos", type="string", length=50, nullable=true)
*/
private $apellidos;
/* Customized code */
/**
* #ORM\OneToMany(targetEntity="GuiasDocentes\AppBundle\Entity\Hilo", mappedBy="consultanteemail")
* #Assert\Valid()
*/
private $hilos;
public function __construct(){
$this->hilos = new ArrayCollection();
}
public function setHilos (Hilo $hilo){
$this->hilos[]=$hilo;
}
public function addHilo (\GuiasDocentes\AppBundle\Entity\Hilo $hilo){
$this->hilos[] = $hilo;
}
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/* End customize code */
...
public function contactoAction (Request $request){
$session = $request->getSession();
$perfil = $session->get('perfil');
$consultaHasAsignatura = new ConsultaHasAsignatura();
$form = $this->createForm(new ConsultaHasAsignaturaType(), $consultaHasAsignatura);
if ($request->isMethod('POST')){
$form->handleRequest($request);
if($form->isValid()){
$em = $this->getDoctrine()->getManager();
$em->persist($consultaHasAsignatura);
$em->flush();
return $this->redirectToRoute('guias_docentes_app_homepage');
}
}
return $this->render('GuiasDocentesAppBundle:FAQ:contacto.html.twig', array('perfil'=>$perfil,
'form' => $form->createView()
));
}
I have two entities:
/**
* Device
*
* #ORM\Table(name="device", indexes={#ORM\Index(name="referente_id", columns={"referente_id"})})
* #ORM\Entity
*/
class Device
{
/**
* #var string
*
* #ORM\Column(name="id_device", type="string", length=60)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $idDevice;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Acme\BasicCmsBundle\Entity\Carrier", mappedBy="device")
*/
private $carrier;
/**
* Carrier
*
* #ORM\Table(name="carrier")
* #ORM\Entity
*/
class Carrier
{
/**
* #var string
*
* #ORM\Column(name="rag_soc", type="string", length=200, nullable=true)
*/
private $ragSoc;
/**
* #var string
*
* #ORM\Column(name="via", type="string", length=150, nullable=true)
*/
private $via;
/**
* #var string
*
* #ORM\Column(name="nr", type="string", length=8, nullable=true)
*/
private $nr;
/**
* #var string
*
* #ORM\Column(name="citta", type="string", length=100, nullable=true)
*/
private $citta;
/**
* #var string
*
* #ORM\Column(name="naz", type="string", length=5, nullable=true)
*/
private $naz;
/**
* #var string
*
* #ORM\Column(name="tel", type="string", length=20, nullable=true)
*/
private $tel;
/**
* #var integer
*
* #ORM\Column(name="id_carrier", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $idCarrier;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Acme\BasicCmsBundle\Entity\Device", inversedBy="carrier")
* #ORM\JoinTable(name="carrier_device",
* joinColumns={
* #ORM\JoinColumn(name="carrier_id", referencedColumnName="id_carrier")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="device_id", referencedColumnName="id_device")
* }
* )
*/
private $device;
The entities have a many-to-many relation. I have created the admin page:
class CarrierAdmin extends Admin
{
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('rag_soc', 'string')
->addIdentifier('citta', 'string')
->add('device', null, array('associated_property' => 'id_device'))
->add('_action', 'actions', array(
'actions' => array(
'view' => array(),
'edit' => array(),
'delete' => array(),
)
));
}
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('Carrier Information', array('class' => 'col-md-8', 'box_class' => 'box box-solid box-danger', 'description' => 'Lorem ipsum',))
->add('rag_soc', 'text')
->add('citta', 'text')
->end()
->with('Devices', array('class' => 'col-md-8', 'box_class' => 'box box-solid box-danger', 'description' => 'Lorem ipsum',))
->add('device', 'sonata_type_model_autocomplete', array('property'=>'idDevice', 'multiple' => true,))
->end();
}
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper->add('ragSoc');
$datagridMapper->add('citta', null, array('show_filter'=>true))
->add('device');
}
protected function configureShowFields(ShowMapper $showMapper)
{
$showMapper->add('rag_soc');
}
class DeviceAdmin extends Admin
{
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('idDevice', 'string');
}
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('form.group_general', array('class' => 'col-md-8', 'box_class' => 'box box-solid box-danger', 'description' => 'Lorem ipsum',))
->add('idDevice', 'text')
->end();
}
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper->add('idDevice');
}
public function getExportFormats()
{
return array();
}
}
In CarrierAdmin I define in the form the device item as sonata_type_model_autocomplete. My problem is that adding or deleting a device causes a "property not found" exception. Symfony changes the property name from Device to Devouce.
The error is in PropertyAccessor:writeProperty function, which invokes StringUtil::singularify($camelized) which changes the property name.
Is it a bug?
Temporarily I have solved it by adding the original property name to the result of StringUtil::singularify($camelized).
I have 5 Entities
Entity\Book:
class Book
{
/**
* #var integer
*
* #ORM\Column(name="b_id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $bId;
/**
* #var string
*
* #ORM\Column(name="b_foto", type="string", length=255, nullable=true)
*/
private $bFoto;
/**
* #var string
*
* #ORM\Column(name="b_title", type="string", length=255, nullable=false)
*/
private $bTitle;
public $author;
public $heading;
}
Entity\Author
/**
* Author
*
* #ORM\Table(name="author")
* #ORM\Entity
*/
class Author
{
/**
* #var integer
*
* #ORM\Column(name="a_id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $aId;
/**
* #var string
*
* #ORM\Column(name="a_firstname", type="string", length=100, nullable=false)
*/
private $aFirstname;
/**
* #var string
*
* #ORM\Column(name="a_lastname", type="string", length=100, nullable=false)
*/
private $aLastname;
}
Entity\Heading
/**
* Heading
*
* #ORM\Table(name="heading")
* #ORM\Entity
*/
class Heading
{
/**
* #var integer
*
* #ORM\Column(name="h_id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $hId;
/**
* #var string
*
* #ORM\Column(name="h_title", type="string", length=100, nullable=false)
*/
private $hTitle;
}
Entity\BooksAuthor
/**
* BooksAuthor
*
* #ORM\Table(name="books_author", indexes={#ORM\Index(name="book_in", columns={"b_id"}), #ORM\Index(name="author_in", columns={"a_id"})})
* #ORM\Entity
*/
class BooksAuthor
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \AppBundle\Entity\Book
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Book")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="b_id", referencedColumnName="b_id")
* })
*/
private $b;
/**
* #var \AppBundle\Entity\Author
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Author")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="a_id", referencedColumnName="a_id")
* })
*/
private $a;
}
Entity\BooksHeading
class BooksHeading
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \AppBundle\Entity\Heading
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Heading")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="h_id", referencedColumnName="h_id")
* })
*/
private $h;
/**
* #var \AppBundle\Entity\Book
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Book")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="b_id", referencedColumnName="b_id")
* })
*/
private $b;
}
I use SonataAdmin and when I update my Entity\Book I want to update and another Entities.
That`s my BookAdmin
namespace AppBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
class BookAdmin extends Admin
{
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('bTitle', null , array('label' => 'Название'))
->add('author', 'sonata_type_model', array('class' => 'AppBundle\Entity\Author',
'label'=>"Авторы",
'multiple'=>true,
'required'=>false,
'multiple'=>true,
'expanded'=> true,
'by_reference' => false,),
array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position')
)
->add('heading', 'sonata_type_model', array('class' => 'AppBundle\Entity\Heading',
'label'=>'Рубрика',
'required'=>false,
'multiple'=>true,
'expanded'=> true,
'by_reference' => false,),
array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'id',))
->add('bFoto','file',array('label'=>'Обложка',
'data_class'=> null,
'required'=>false,
))
;
}
// Fields to be shown on filter forms
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
//->add('author', null , array('label' => 'Автор',
// 'class' => 'AppBundle\Entity\BookAuthor',
// ))
//->add('heading', null, array('label' => 'Рубрика',
//'class' => 'AppBundle\Entity\BookHeading',
//))
;
}
// Fields to be shown on lists
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('b_id', null, array('label' => 'ID'))
->add('bTitle', null , array('label' => 'Название'))
;
}
}
Can you help me?
You need to indicate the cascade type in your entities BooksHeading and BooksAuthor,
Try this:
#ORM\ManyToOne(targetEntity="AppBundle\Entity\Heading", casccade="persist")
I have an issue with Sonata admin form...
I would like to insert music in a album with position...
My issue is when I create an album... I can add many as I want AlbumHasMusic... But when I submit my form... Each AlbumHasMusic have a null album whereas music and positions are ok.
How could I put album id to each AlbumHasMusic ?
These are my Entities :
Album:
/**
* Album
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="AppBundle\Entity\AlbumRepository")
* #ORM\HasLifecycleCallbacks()
*/
class Album
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="titre", type="string", length=255)
*/
private $titre;
/**
* #var UploadedFile
*/
private $cover;
/**
* #var String
*
* #ORM\Column(name="filename", type="string", length=255, nullable=true)
*/
private $covername;
/**
*
* #var Array<AlbumHasMusiques>
* #ORM\OneToMany(targetEntity="AppBundle\Entity\AlbumHasMusiques", mappedBy="album", cascade={"persist"})
*/
private $albumHasMusiques;
/**
* #var \DateTime
*
* #ORM\Column(name="updated", type="time", nullable=true)
*/
private $updated;
}
AlbumHasMusic:
/**
* AlbumHasMusiques
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="AppBundle\Entity\AlbumHasMusiquesRepository")
*/
class AlbumHasMusiques
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Album
*
* #ORM\ManyToOne(targetEntity="Album")
* #ORM\JoinColumn(name="album_id", referencedColumnName="id")
*/
private $album;
/**
* #var Musique
*
* #ORM\ManyToOne(targetEntity="Musique")
* #ORM\JoinColumn(name="musique_id", referencedColumnName="id")
*/
private $musique;
/**
* #var integer
*
* #ORM\Column(name="position", type="integer")
*/
private $position;
}
Music:
/**
* Musique
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="AppBundle\Entity\MusiqueRepository")
* #ORM\HasLifecycleCallbacks()
*/
class Musique
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \DateTime
*
* #ORM\Column(name="duree", type="time", nullable=true)
*/
private $duree;
/**
* #var \DateTime
*
* #ORM\Column(name="updated", type="time", nullable=true)
*/
private $updated;
/**
* #var string
*/
private $file;
/**
* #var String
*
* #ORM\Column(name="filename", type="string", length=255, nullable=true)
*/
private $filename;
/**
* #var string
*
* #ORM\Column(name="titre", type="string", length=255, nullable=true)
*/
private $titre;
/**
* #var Genre
*
* #ORM\ManyToOne(targetEntity="Genre", inversedBy="musiques")
* #ORM\JoinColumn(name="genre_id", referencedColumnName="id", nullable=false)
*/
private $genre;
/**
* #ORM\ManyToMany(targetEntity="MotClef", inversedBy="musiques")
*/
private $motsClef;
}
I would like to do something like Galeries and media of Sonata Media Bundle.
And this is my AlbumAdmin:
class AlbumAdmin extends Admin
{
/**
* #param FormMapper $formMapper
*/
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('titre')
->add('covername')
->add('updated')
->add('albumHasMusiques', 'sonata_type_collection', array(
'cascade_validation' => true,
'by_reference' => false,
), array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position',
'link_parameters' => array('context' => 'default'),
'admin_code' => 'app.admin.album_has_musiques',
)
)
;
}
/**
* {#inheritdoc}
*/
public function prePersist($album)
{
$album->setAlbumHasMusiques($album->getAlbumHasMusiques());
}
/**
* {#inheritdoc}
*/
public function preUpdate($album)
{
$album->setAlbumHasMusiques($album->getAlbumHasMusiques());
}
}
And AlbumHasMusicAdmin :
class AlbumHasMusiquesAdmin extends Admin
{
/**
* #param FormMapper $formMapper
*/
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('musique', 'sonata_type_model_list', array('required' => true), array(
'link_parameters' => ['context' => 'default'],
))
->add('position', 'hidden')
;
}
}
Do you have any idea ?
I think that you missed something in the addAlbumHasMusiques() function in your album entity : make sure that you wrote it like that :
public function addAlbumHasMusiques(\AppBundle\Entity\AlbumHasMusiques $albumHasMusiques) {
$albumHasMusiques->setAlbum($this); // The important line !!!!
$this->albumHasMusiques[] = $albumHasMusiques;
return $this;
}