I'm having problems creating my form for creating a course. This is a part of my database scheme for which I'm trying to create a form:
So which I'm trying to do is create a course where I can create sessions and dates (moment) attached to that session. It should look something like this:
In my CourseAdmin class I have:
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('name', 'text', array('label' => 'Naam'))
->add('description', 'textarea', array('label' => 'Beschrijving'))
->add('materials', 'textarea', array('label' => 'Benodigde materialen'))
->add('numberOfParticipants', 'number', array('label' => 'Aantal deelnembers'))
->add('numberOfDays', 'number', array('label' => 'Aantal dagen'))
->add('price', 'number', array('label' => 'Prijs'))
->add('priceKmo', 'number', array('label' => 'KMO-portefeuille Prijs'))
->add('location', 'sonata_type_model', array('expanded' => true, 'by_reference' => false, 'multiple' => true, 'btn_add' => false))
->add('session', 'sonata_type_collection', array(
'by_reference' => false,
'type_options' => array(
// Prevents the "Delete" option from being displayed
'delete' => false,
'delete_options' => array(
// You may otherwise choose to put the field but hide it
'type' => 'hidden',
// In that case, you need to fill in the options as well
'type_options' => array(
'mapped' => false,
'required' => false,
)
)
)
), array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position'
))
;
}
In my SessionAdmin class I have:
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('type', 'text', array('label' => 'Type opleiding (Dag / Avond)'))
->add('moment', 'sonata_type_collection', array(
'by_reference' => false,
'type_options' => array(
// Prevents the "Delete" option from being displayed
'delete' => false,
'delete_options' => array(
// You may otherwise choose to put the field but hide it
'type' => 'hidden',
// In that case, you need to fill in the options as well
'type_options' => array(
'mapped' => false,
'required' => false,
)
)
)
), array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position'
))
;
}
And in my MomentAdmin class I have:
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('time', 'date', array('label' => 'Datum'))
;
}
The problem in my form is when I try to add a moment (date) to my session I get the following error:
FatalErrorException: Error: Call to a member function getName() on null in /myproject/app/cache/dev/classes.php line 9772
So, I can add a session but when I try to add a moment to my session I'm getting the error ... .
When I look in the file classes.php on rule 9771 and 9772 there is:
$childFormBuilder = $this->getChildFormBuilder($formBuilder, $elementId);
$fieldDescription = $admin->getFormFieldDescription($childFormBuilder->getName());
The $childFormBuilder
is null.
When I look at that function than I get this:
public function getChildFormBuilder(FormBuilder $formBuilder, $elementId)
{
foreach (new FormBuilderIterator($formBuilder) as $name => $formBuilder) {
if ($name == $elementId) {
return $formBuilder;
}
}
return;
}
When I do a var_dump of $name and $elementId like this:
public function getChildFormBuilder(FormBuilder $formBuilder, $elementId)
{
foreach (new FormBuilderIterator($formBuilder) as $name => $formBuilder) {
var_dump("name: " . $name);
var_dump("elementId: " . $elementId);
if ($name == $elementId) {
return $formBuilder;
}
}
die;
return;
}
And push on the Add new button like the following picture:
Then I get this output:
name: s56cda71d2daa0_name
elementId: s56cda71d2daa0_session_0_moment
name: s56cda71d2daa0_description
elementId: s56cda71d2daa0_session_0_moment
name: s56cda71d2daa0_materials
elementId: s56cda71d2daa0_session_0_moment
name: s56cda71d2daa0_numberOfParticipants
elementId: s56cda71d2daa0_session_0_moment
name: s56cda71d2daa0_numberOfDays
elementId: s56cda71d2daa0_session_0_moment
name: s56cda71d2daa0_price
elementId: s56cda71d2daa0_session_0_moment
name: s56cda71d2daa0_priceKmo
elementId: s56cda71d2daa0_session_0_moment
name: s56cda71d2daa0_location
elementId: s56cda71d2daa0_session_0_moment
name: s56cda71d2daa0_session
elementId: s56cda71d2daa0_session_0_moment
In all my entities I have a __toString function. An example in my Course entity:
public function __toString()
{
if(!is_null($this->name))
{
return $this->name;
}
else{
return "";
}
}
What could be the problem here? I'm really stuck with this. I've also posted an issue on the github repo of Sonata Admin but no answers ...
My entities:
Course Entity:
<?php
namespace Studyx\EnrolmentBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Course
*
* @ORM\Table(name="course")
* @ORM\Entity
*/
class Course
{
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="description", type="text", nullable=false)
*/
private $description;
/**
* @var string
*
* @ORM\Column(name="materials", type="text", nullable=true)
*/
private $materials;
/**
* @var integer
*
* @ORM\Column(name="number_of_participants", type="integer", nullable=true)
*/
private $numberOfParticipants;
/**
* @var integer
*
* @ORM\Column(name="number_of_days", type="integer", nullable=true)
*/
private $numberOfDays;
/**
* @var string
*
* @ORM\Column(name="price", type="decimal", nullable=true)
*/
private $price;
/**
* @var string
*
* @ORM\Column(name="price_kmo", type="decimal", nullable=true)
*/
private $priceKmo;
/**
* @var integer
*
* @ORM\Column(name="ID", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="Studyx\EnrolmentBundle\Entity\Location", inversedBy="course")
* @ORM\JoinTable(name="course_has_location",
* joinColumns={
* @ORM\JoinColumn(name="course_ID", referencedColumnName="ID")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="location_ID", referencedColumnName="ID")
* }
* )
*/
private $location;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="Studyx\EnrolmentBundle\Entity\Session", mappedBy="course")
*/
private $session;
/**
* Add session
*
* @param \Studyx\EnrolmentBundle\Entity\Session $session
* @return Session
*/
public function addSession(\Studyx\EnrolmentBundle\Entity\Session $session)
{
$this->session[] = $session;
return $this;
}
/**
* Remove session
*
* @param \Studyx\EnrolmentBundle\Entity\Session $session
*/
public function removeSession(\Studyx\EnrolmentBundle\Entity\Session $session)
{
$this->session->removeElement($session);
}
/**
* Get session
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getSession()
{
return $this->session;
}
/**
* Constructor
*/
public function __construct()
{
$this->location = new \Doctrine\Common\Collections\ArrayCollection();
}
public function __toString()
{
if(!is_null($this->name))
{
return $this->name;
}
else{
return "";
}
}
/**
* Set name
*
* @param string $name
* @return Course
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set description
*
* @param string $description
* @return Course
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set materials
*
* @param string $materials
* @return Course
*/
public function setMaterials($materials)
{
$this->materials = $materials;
return $this;
}
/**
* Get materials
*
* @return string
*/
public function getMaterials()
{
return $this->materials;
}
/**
* Set numberOfParticipants
*
* @param integer $numberOfParticipants
* @return Course
*/
public function setNumberOfParticipants($numberOfParticipants)
{
$this->numberOfParticipants = $numberOfParticipants;
return $this;
}
/**
* Get numberOfParticipants
*
* @return integer
*/
public function getNumberOfParticipants()
{
return $this->numberOfParticipants;
}
/**
* Set numberOfDays
*
* @param integer $numberOfDays
* @return Course
*/
public function setNumberOfDays($numberOfDays)
{
$this->numberOfDays = $numberOfDays;
return $this;
}
/**
* Get numberOfDays
*
* @return integer
*/
public function getNumberOfDays()
{
return $this->numberOfDays;
}
/**
* Set price
*
* @param string $price
* @return Course
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* @return string
*/
public function getPrice()
{
return $this->price;
}
/**
* Set priceKmo
*
* @param string $priceKmo
* @return Course
*/
public function setPriceKmo($priceKmo)
{
$this->priceKmo = $priceKmo;
return $this;
}
/**
* Get priceKmo
*
* @return string
*/
public function getPriceKmo()
{
return $this->priceKmo;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add location
*
* @param \Studyx\EnrolmentBundle\Entity\Location $location
* @return Course
*/
public function addLocation(\Studyx\EnrolmentBundle\Entity\Location $location)
{
$this->location[] = $location;
return $this;
}
/**
* Remove location
*
* @param \Studyx\EnrolmentBundle\Entity\Location $location
*/
public function removeLocation(\Studyx\EnrolmentBundle\Entity\Location $location)
{
$this->location->removeElement($location);
}
/**
* Get location
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getLocation()
{
return $this->location;
}
}
Session Entity:
<?php
namespace Studyx\EnrolmentBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Session
*
* @ORM\Table(name="session")
* @ORM\Entity
*/
class Session
{
/**
* @var string
*
* @ORM\Column(name="type", type="string", length=45, nullable=false)
*/
private $type;
/**
* @var integer
*
* @ORM\Column(name="ID", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var \Studyx\EnrolmentBundle\Entity\Course
*
* @ORM\ManyToOne(targetEntity="Studyx\EnrolmentBundle\Entity\Course", inversedBy="session")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="course_ID", referencedColumnName="ID")
* })
*/
private $course;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="Studyx\EnrolmentBundle\Entity\Moment", mappedBy="session")
*/
private $moment;
/**
* Add moment
*
* @param \Studyx\EnrolmentBundle\Entity\Moment $moment
* @return Moment
*/
public function addMoment(\Studyx\EnrolmentBundle\Entity\Moment $moment)
{
$this->moment[] = $moment;
return $this;
}
/**
* Remove moment
*
* @param \Studyx\EnrolmentBundle\Entity\Moment $moment
*/
public function removeMoment(\Studyx\EnrolmentBundle\Entity\Moment $moment)
{
$this->moment->removeElement($moment);
}
/**
* Get moment
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getMoment()
{
return $this->moment;
}
public function __toString()
{
if(!is_null($this->type))
{
return $this->type;
}
else{
return "";
}
}
/**
* Set type
*
* @param string $type
* @return Session
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set course
*
* @param \Studyx\EnrolmentBundle\Entity\Course $course
* @return Session
*/
public function setCourse(\Studyx\EnrolmentBundle\Entity\Course $course = null)
{
$this->course = $course;
return $this;
}
/**
* Get course
*
* @return \Studyx\EnrolmentBundle\Entity\Course
*/
public function getCourse()
{
return $this->course;
}
}
Moment Entity:
<?php
namespace Studyx\EnrolmentBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Moment
*
* @ORM\Table(name="moment")
* @ORM\Entity
*/
class Moment
{
/**
* @var \DateTime
*
* @ORM\Column(name="time", type="datetime", nullable=false)
*/
private $time;
/**
* @var integer
*
* @ORM\Column(name="ID", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var \Studyx\EnrolmentBundle\Entity\Session
*
* @ORM\ManyToOne(targetEntity="Studyx\EnrolmentBundle\Entity\Session")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="session_ID", referencedColumnName="ID")
* })
*/
private $session;
public function __toString()
{
if(!is_null($this->time))
{
return $this->time;
}
else{
return "";
}
}
/**
* Set time
*
* @param \DateTime $time
* @return Moment
*/
public function setTime($time)
{
$this->time = $time;
return $this;
}
/**
* Get time
*
* @return \DateTime
*/
public function getTime()
{
return $this->time;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set session
*
* @param \Studyx\EnrolmentBundle\Entity\Session $session
* @return Moment
*/
public function setSession(\Studyx\EnrolmentBundle\Entity\Session $session = null)
{
$this->session = $session;
return $this;
}
/**
* Get session
*
* @return \Studyx\EnrolmentBundle\Entity\Session
*/
public function getSession()
{
return $this->session;
}
}
UPDATE:
I've added some var_dumps to my function getChildFormBuilder like this:
public function getChildFormBuilder(FormBuilder $formBuilder, $elementId)
{
foreach (new FormBuilderIterator($formBuilder) as $name => $formBuilder) {
if ($name == $elementId) {
return $formBuilder;
}
}
var_dump(__METHOD__);
var_dump($elementId);
var_dump(debug_backtrace());
return;
}
The result is this:
string 'Sonata\AdminBundle\Admin\AdminHelper::getChildFormBuilder' (length=57)
string 's56cdfa72c4dea_session_0_moment' (length=31)
array (size=8)
0 =>
array (size=7)
'file' => string '/Applications/MAMP/htdocs/studyx_enrolments/app/cache/dev/classes.php' (length=69)
'line' => int 9774
'function' => string 'getChildFormBuilder' (length=19)
'class' => string 'Sonata\AdminBundle\Admin\AdminHelper' (length=36)
'object' =>
object(Sonata\AdminBundle\Admin\AdminHelper)[339]
protected 'pool' =>
object(Sonata\AdminBundle\Admin\Pool)[104]
...
'type' => string '->' (length=2)
'args' =>
array (size=2)
0 =>
object(Symfony\Component\Form\FormBuilder)[436]
...
1 => &string 's56cdfa72c4dea_session_0_moment' (length=31)
1 =>
array (size=7)
'file' => string '/Applications/MAMP/htdocs/studyx_enrolments/vendor/sonata-project/admin-bundle/Controller/HelperController.php' (length=110)
'line' => int 95
'function' => string 'appendFormFieldElement' (length=22)
'class' => string 'Sonata\AdminBundle\Admin\AdminHelper' (length=36)
'object' =>
object(Sonata\AdminBundle\Admin\AdminHelper)[339]
protected 'pool' =>
object(Sonata\AdminBundle\Admin\Pool)[104]
...
'type' => string '->' (length=2)
'args' =>
array (size=3)
0 =>
object(Studyx\EnrolmentBundle\Admin\CourseAdmin)[370]
...
1 =>
object(Studyx\EnrolmentBundle\Entity\Course)[415]
...
2 => &string 's56cdfa72c4dea_session_0_moment' (length=31)
2 =>
array (size=5)
'function' => string 'appendFormFieldElementAction' (length=28)
'class' => string 'Sonata\AdminBundle\Controller\HelperController' (length=46)
'object' =>
object(Sonata\AdminBundle\Controller\HelperController)[244]
protected 'twig' =>
object(Twig_Environment)[220]
...
protected 'helper' =>
object(Sonata\AdminBundle\Admin\AdminHelper)[339]
...
protected 'pool' =>
object(Sonata\AdminBundle\Admin\Pool)[104]
...
protected 'validator' =>
object(Symfony\Component\Validator\Validator)[340]
...
'type' => string '->' (length=2)
'args' =>
array (size=1)
0 =>
object(Symfony\Component\HttpFoundation\Request)[6]
...
3 =>
array (size=4)
'file' => string '/Applications/MAMP/htdocs/studyx_enrolments/app/bootstrap.php.cache' (length=67)
'line' => int 2957
'function' => string 'call_user_func_array' (length=20)
'args' =>
array (size=2)
0 => &
array (size=2)
...
1 => &
array (size=1)
...
4 =>
array (size=7)
'file' => string '/Applications/MAMP/htdocs/studyx_enrolments/app/bootstrap.php.cache' (length=67)
'line' => int 2931
'function' => string 'handleRaw' (length=9)
'class' => string 'Symfony\Component\HttpKernel\HttpKernel' (length=39)
'object' =>
object(Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel)[300]
protected 'container' =>
object(appDevDebugProjectContainer)[304]
...
protected 'dispatcher' =>
object(Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher)[299]
...
protected 'resolver' =>
object(Symfony\Component\HttpKernel\Controller\TraceableControllerResolver)[249]
...
'type' => string '->' (length=2)
'args' =>
array (size=2)
0 =>
object(Symfony\Component\HttpFoundation\Request)[6]
...
1 => &int 1
5 =>
array (size=7)
'file' => string '/Applications/MAMP/htdocs/studyx_enrolments/app/bootstrap.php.cache' (length=67)
'line' => int 3060
'function' => string 'handle' (length=6)
'class' => string 'Symfony\Component\HttpKernel\HttpKernel' (length=39)
'object' =>
object(Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel)[300]
protected 'container' =>
object(appDevDebugProjectContainer)[304]
...
protected 'dispatcher' =>
object(Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher)[299]
...
protected 'resolver' =>
object(Symfony\Component\HttpKernel\Controller\TraceableControllerResolver)[249]
...
'type' => string '->' (length=2)
'args' =>
array (size=3)
0 =>
object(Symfony\Component\HttpFoundation\Request)[6]
...
1 => &int 1
2 => &boolean true
6 =>
array (size=7)
'file' => string '/Applications/MAMP/htdocs/studyx_enrolments/app/bootstrap.php.cache' (length=67)
'line' => int 2333
'function' => string 'handle' (length=6)
'class' => string 'Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel' (length=73)
'object' =>
object(Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel)[300]
protected 'container' =>
object(appDevDebugProjectContainer)[304]
...
protected 'dispatcher' =>
object(Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher)[299]
...
protected 'resolver' =>
object(Symfony\Component\HttpKernel\Controller\TraceableControllerResolver)[249]
...
'type' => string '->' (length=2)
'args' =>
array (size=3)
0 =>
object(Symfony\Component\HttpFoundation\Request)[6]
...
1 => &int 1
2 => &boolean true
7 =>
array (size=7)
'file' => string '/Applications/MAMP/htdocs/studyx_enrolments/web/app_dev.php' (length=59)
'line' => int 29
'function' => string 'handle' (length=6)
'class' => string 'Symfony\Component\HttpKernel\Kernel' (length=35)
'object' =>
object(AppKernel)[5]
protected 'bundles' =>
array (size=22)
...
protected 'bundleMap' =>
array (size=22)
...
protected 'container' =>
object(appDevDebugProjectContainer)[304]
...
protected 'rootDir' => string '/Applications/MAMP/htdocs/studyx_enrolments/app' (length=47)
protected 'environment' => string 'dev' (length=3)
protected 'debug' => boolean true
protected 'booted' => boolean true
protected 'name' => string 'app' (length=3)
protected 'startTime' => float 1456339594.61
protected 'loadClassCache' =>
array (size=2)
...
'type' => string '->' (length=2)
'args' =>
array (size=1)
0 =>
object(Symfony\Component\HttpFoundation\Request)[6]
...
UPDATE 2:
I've changed the require in my composer.json to "sonata-project/admin-bundle": "^2.4@dev" and updated with composer. But now I'm getting this error:
ContextErrorException: Warning: Illegal string offset 'admin' in app/cache/dev/classes.php line 10482
The error is in this function:
public function getDashboardGroups()
{
$groups = $this->adminGroups;
foreach ($this->adminGroups as $name => $adminGroup) {
if (isset($adminGroup['items'])) {
foreach ($adminGroup['items'] as $key => $item) {
if (''!= $item['admin']) {
$admin = $this->getInstance($item['admin']);
if ($admin->showIn(Admin::CONTEXT_DASHBOARD)) {
$groups[$name]['items'][$key] = $admin;
} else {
unset($groups[$name]['items'][$key]);
}
}
else {
unset($groups[$name]['items'][$key]);
}
}
}
if (empty($groups[$name]['items'])) {
unset($groups[$name]);
}
}
return $groups;
}
The errors in on line : if (''!= $item['admin']) {
.
In my config.yml I have:
sonata_admin:
title: Studyx
title_logo: bundles/studyxenrolment/images/logo.png
templates:
layout: StudyxEnrolmentBundle:Admin:standard_layout.html.twig
edit: StudyxEnrolmentBundle:CRUD:edit.html.twig
user_block: StudyxEnrolmentBundle:Admin:user_block.html.twig
# search: SonataAdminBundle:Core:search.html.twig
# search_result_block: SonataAdminBundle:Block:block_search_result.html.twig
dashboard:
groups:
studyx.admin.group.inschrijvingen:
label: Inschrijvingen
items: ~
item_adds:
- sonata.admin.enrolment
studyx.admin.group.algemeen:
label: Algemeen
items: ~
item_adds:
- sonata.admin.course
- sonata.admin.student
studyx.admin.group.extra:
label: Extra
items: ~
item_adds:
- sonata.admin.location
blocks:
-
position: top
class: col-md-12
type: sonata.admin.block.admin_list
So I think the function getDashboardGroups is called there.
UPDATE 3:
In my composer.json I have now the following:
"sonata-project/block-bundle": "~2.3",
"sonata-project/admin-bundle": "^2.4@dev",
"sonata-project/doctrine-orm-admin-bundle": "2.3.*",
"sonata-project/formatter-bundle": "^2.3"
Should I update them all to ^2.4@dev
?
This error occurs because you have more than two level of nested collection forms, and it's currently not yet supported in any release of sonata-admin.
From @rande (owner) and sonata maintainers at issues #262, #1228, #1327 and #1971 :
This is still not supported for now ....
You can also look at this old PR #1971 which should solve the problem for some use cases only.
The solution I propose you is to implement the fix provided by the last opened PR #2985.
Because the PR is not merged, you need to tell composer to load it rather than the current (not-working as expected) version. (see composer and VCS).
Hope the PR is merged soon.
Until it is, feel free to fix your problem at the moment by using it directly, as several people do.
UPDATE
The Pull Request #3553 has been recently merged and fix the problem of the nested collections at > 2 levels (nested in nested).
To get the fixed release, you must use the dev-master
tag of the bundle (at least from the commit 926f159 representing the merge of the PR).
I tried it and it works well with the following requirement:
// composer.json
"require": {
"sonata-project/admin-bundle": "^2.4@dev",
...
},
I hope you can easily upgrade the bundle in order to get the fix.
Update2
Apparently, your composer doesn't take the last changes of the branch.
The fix provided by the PR #2739 has been merged 6 days ago.
To fix this last one (hope), you need to change a very short code block in the AddDepencyCallsCompilerPass
located in vendor/sonata-project/admin-bundle/DependencyInjection/Compiler/AddDependencyCallsCompilerPass
.
At line 95, replace this line :
$groupDefaults[$resolvedGroupName]['items'][] = $id;
To those ones:
$groupDefaults[$resolvedGroupName]['items'][] = array(
'admin' => $id,
'label' => !empty($attributes['label']) ? $attributes['label'] : '',
'route' => '',
'route_params' => array(),
);
Like it's done by the PR (it's the only needed change to make it working).
I would make the fix manually because it's very new, and after some days/weeks, run the following commands:
composer clear-cache
and composer update sonata-project/admin-bundle
You should try it now before adding the fix manually, maybe the changes will be added.
Also, you can use the link about composer and VCS I given at the begin of my answer and require the fix directly. It's at your own appreciation because of it's a solution at the moment.
And last, be patient, the fixes will be merged in stable releases soon.
public function getChildFormBuilder(FormBuilder $formBuilder, $elementId)
{
foreach (new FormBuilderIterator($formBuilder) as $name => $formBuilder) {
if ($name == $elementId) {
return $formBuilder;
}
}
return;
}
Dumping the name and element id within the loop won't accomplish anything. Your application obviously crashes when there is nothing to iterate - it then walks through the loop, exits and goes to the last line where NULL
is returned.
I suggest you dump the element id just after the loop, like the following. The use of debug_backtrace might also help:
public function getChildFormBuilder(FormBuilder $formBuilder, $elementId)
{
foreach (new FormBuilderIterator($formBuilder) as $name => $formBuilder) {
if ($name == $elementId) {
return $formBuilder;
}
}
var_dump(__METHOD__);
var_dump($elementId);
var_dump(debug_backtrace());
return;
}
来源:https://stackoverflow.com/questions/35258776/nested-collection-fields-in-sonata-admin-2-3