2016-02-07 4 views
22

У меня возникли проблемы с созданием формы для создания курса. Это часть моей схемы базы данных, для которого я пытаюсь создать форму:Вложенные поля коллекции в Sonata Admin (2.3)

Так, который я пытаюсь сделать, это создать курс, где я могу создать сессии и даты (момент) прилагается к этой сессии. Это должно выглядеть примерно так:

enter image description here

В моем классе CourseAdmin у меня есть:

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' 
     )) 
    ; 
} 

В моей SessionAdmin классе у меня есть:

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' 
     )) 
     ; 
} 

И в мой MomentAdmin класс у меня есть:

protected function configureFormFields(FormMapper $formMapper) 
{ 
    $formMapper 
     ->add('time',  'date',  array('label' => 'Datum')) 
    ; 
} 

Проблема в моей форме, когда я пытаюсь добавить момент (дату) в моей сессии, я получаю следующее сообщение об ошибке:

FatalErrorException: Error: Call to a member function getName() on null in /myproject/app/cache/dev/classes.php line 9772

Таким образом, я могу добавить но когда я пытаюсь добавить момент на свою сессию, я получаю ошибку ....

Когда я смотрю в файле classes.php на правиле 9771 и 9772 есть:

$childFormBuilder = $this->getChildFormBuilder($formBuilder, $elementId); 
$fieldDescription = $admin->getFormFieldDescription($childFormBuilder->getName()); 

$childFormBuilder является нуль.

Когда я смотрю на эту функцию, чем я получаю это:

public function getChildFormBuilder(FormBuilder $formBuilder, $elementId) 
{ 
    foreach (new FormBuilderIterator($formBuilder) as $name => $formBuilder) { 
     if ($name == $elementId) { 
      return $formBuilder; 
     } 
    } 
    return; 
} 

Когда я делаю var_dump от $ имени и $ elementId так:

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; 
} 

и нажать на кнопку Добавить как показано на следующем рисунке:

enter image description here

n Я получаю этот выход:

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 

Во всех моих сущностях у меня есть функция __toString. Пример в моей организации курса:

public function __toString() 
{ 
    if(!is_null($this->name)) 
    { 
     return $this->name; 
    } 
    else{ 
     return ""; 
    } 
} 

В чем проблема? Я действительно застрял в этом. Я также разместил issue в реестре github от Sonata Admin, но ответов нет ...

Мои объекты:

курс 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; 
    } 
} 

сеансами:

<?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 En Tity:

<?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:

Я добавил некоторые var_dumps к моей функции getChildFormBuilder так:

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; 
} 

Результат таков:

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:

Я изменил требуется в моем composer.json к «соната-проект/админ-расслоении»: «^[email protected]» и обновляется с композитором. Но теперь я получаю эту ошибку:

ContextErrorException: Warning: Illegal string offset 'admin' in app/cache/dev/classes.php line 10482

Ошибка находится в этой функции:

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; 
} 

Ошибки в на линии: if (''!= $item['admin']) {.

В моей config.yml у меня есть:

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 

Так что я думаю, что функция getDashboardGroups называется там.

UPDATE 3:

В моей composer.json я сейчас следующее:

"sonata-project/block-bundle": "~2.3", 
"sonata-project/admin-bundle": "^[email protected]", 
"sonata-project/doctrine-orm-admin-bundle": "2.3.*", 
"sonata-project/formatter-bundle": "^2.3" 

Должен ли я обновить их всех ^[email protected]?

+0

дайте нам код блока, который отвечает за это FatalErrorException (строка 9772 ...) –

+0

Очевидно, ваш метод '$ this-> getChildFormBuilder ($ formBuilder, $ elementId);' не возвращает formBuilder, а 'null вместо этого. Можете ли вы поделиться этим кодом? –

+0

Я не вижу ничего странного в этой точке, поэтому я бы начал с добавления каких-либо «var_dumps» в getChildFormBuilder, чтобы проверить переменные '$ elementId' и' $ name' и посмотреть, действительно ли они совпадают. –

ответ

4

Эта ошибка происходит потому, что у вас есть более чем в два уровня вложенности форм сбора, и это в настоящее время не поддерживается в любом выпуске сонатной администратора.

От @rande (владельца) и сонаты сопровождающих по вопросам #262, #1228, #1327 и #1971:

This is still not supported for now ....

Вы также можете посмотреть на этой старой PR #1971, который должен решить проблему только для некоторых случаев применения.

Решение, которое я предлагаю вам, заключается в реализации исправления, предоставленного последним открытым PR #2985.
Поскольку PR не объединен, вам нужно сказать, что композитор загружает его, а не текущую (нерабочую, как ожидалось) версию. (см. composer and VCS).

Надеюсь, что PR будет объединен в ближайшее время.
До тех пор, пока это не так, не стесняйтесь исправить свою проблему на данный момент, используя ее напрямую, как это делают несколько человек.

UPDATE

The Pull Request #3553 был недавно слился и решить проблему вложенных коллекций> 2 уровней (вложено в вложенном).

Чтобы получить фиксированный выпуск, вы должны использовать тег dev-master (по крайней мере, от commit 926f159, представляющий слияние PR).

Я попробовал это, и это хорошо работает со следующими требованиями:

// composer.json 

"require": { 
    "sonata-project/admin-bundle": "^[email protected]", 
    ... 
}, 

Я надеюсь, что вы можете легко обновить пакет, чтобы получить исправление.

Update2

По-видимому, ваш композитор не принимает последние изменения в отрасли.
Исправление, предоставленное PR #2739, было объединено 6 дней назад.

Чтобы исправить это последнее (надежда), вам необходимо изменить очень короткий кодовый блок в AddDepencyCallsCompilerPass, расположенный в vendor/sonata-project/admin-bundle/DependencyInjection/Compiler/AddDependencyCallsCompilerPass.

В строке 95, замените эту строку:

$groupDefaults[$resolvedGroupName]['items'][] = $id; 

Для тех из них:

$groupDefaults[$resolvedGroupName]['items'][] = array(
    'admin'  => $id, 
    'label'  => !empty($attributes['label']) ? $attributes['label'] : '', 
    'route'  => '', 
    'route_params' => array(), 
); 

Как это делается по PR (это только необходимые изменения, чтобы сделать его работу).

Я хотел бы сделать исправление вручную, потому что это очень новый, и через несколько дней/недель, выполните следующие команды:

composer clear-cache и composer update sonata-project/admin-bundle

Вы должны попробовать это сейчас, прежде чем добавлять исправления вручную, может быть, изменения будут добавлены.

Кроме того, вы можете использовать ссылку о композиторе и VCS, которые я дал в начале моего ответа, и требуют исправления напрямую. Это на ваше усмотрение, потому что это решение на данный момент.

И, наконец, будьте терпеливы, исправления скоро будут объединены в стабильные версии.

+0

Спасибо за ваш ответ. Я обновил композитор, но теперь я получаю еще одну ошибку. Я обновил свою тему (ОБНОВЛЕНИЕ 2). Не могли бы вы взглянуть? – nielsv

+0

Можете ли вы сказать мне, где находится метод 'getDashboardGroups' и как/где вы его называете? – chalasr

+0

Я обновляю свою тему. – nielsv

1
public function getChildFormBuilder(FormBuilder $formBuilder, $elementId) 
{ 
    foreach (new FormBuilderIterator($formBuilder) as $name => $formBuilder) { 
     if ($name == $elementId) { 
      return $formBuilder; 
     } 
    } 
    return; 
} 

Сбрасывание имени и элемента в цикле ничего не принесет. Ваше приложение, очевидно, сработает, когда нет ничего, чтобы повторить его, затем он проходит цикл, выходит и переходит к последней строке, где возвращается NULL.

Я предлагаю вам сбросить идентификатор элемента сразу после цикла, как показано ниже.Использование debug_backtrace также может помочь:

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; 
} 
+0

Я обновил свою тему с вашими предложениями. – nielsv

Смежные вопросы