Edit: I have since figured out the issue. Explanation below and my work-around.
I have an app I'm working on for my HR department which will be used to perform employee annual evaluations. The way they've requested it, there are pages of bullet points grouped by subject (Business Sense, Skills, etc), and each bullet point is assigned a score by the reviewer. Every position in the company will have the same three pages of bullet points, but each department may elect to add more for the department as a whole, or for each position.
I have my entity for this designed and working properly.
The issue I'm running into is that I'm having some trouble getting the form to render. Right now, for testing purposes, I'm just rendering the form with {{ form(evaluation) }}. It's built with forms nested in a collection.
I've checked the builders with var_dump, and the EvaluationType (the outer form) shows the pages registred in the form, and if I var_dump the EvaluationPage object, it displays the bullet points registered to the object, but when the form renders, only the LAST bullet point renders. None of the other points from any other page display, only the last one added. I've checked and rechecked, and I'm sure it's something simple, but I can't find the issue.
Here are my code snippets:
EvaluationController (getModernEvaluationLocker just uses dummy data:
namespace Company\PerformanceBundle\Controller;
use Company\PerformanceBundle\Entity\Noncommitable\EvaluationLocker;
use Company\PerformanceBundle\Form\Builders\EvaluationType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class EvaluationController extends Controller
{
/**
* @Route("/strive/evaluation", name="eval")
* @Template("CompanyPerformanceBundle:Evaluation:Evaluation.html.twig")
*/
function evaluationEntryAction()
{
$locker = $this->getModernEvaluationLocker();
$em = $this->getDoctrine()->getManager();
$form = $this->createForm(new EvaluationType($em, $locker));
return array(
'sidebarTitle' => 'Strive Evaluations Manager',
'sidebar' => null,
'function' => 'test',
'title' => 'test',
'evaluation' => $form->createView(),
);
}
private function getModernEvaluationLocker()
{
$locker = new EvaluationLocker();
$locker ->addPage('Brand Pillars and Core Values')
->addBullet('Inspires a passion for the industry and ensures that the needs of all customers (internal and external) are met, benefitting both the customer and organization.')
->addBullet('Completes work to high standards and continually looks for ways to improve performance.')
->addBullet('Delivers remarkable customer service 100% of the time, each and everytime to both our internal and external customers.')
->addPage('Business Acumen')
->addBullet('Clear understanding of The Company’s mission, initiatives and direction.')
->addBullet('Has a broad and deep understanding of the issues that affect the organization, industry and the business environment.');
return $locker;
}
}
EvaluationType (The outer form):
namespace Company\PerformanceBundle\Form\Builders;
use Doctrine\ORM\EntityManager;
use Company\PerformanceBundle\Entity\Noncommitable\EvaluationLocker;
use Company\PerformanceBundle\Entity\Noncommitable\EvaluationLockerPage;
use Company\PerformanceBundle\Form\EventListener\EvaluationPageSubscriber;
use Company\PerformanceBundle\Form\Fields\EvaluationPage;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class EvaluationType extends AbstractType {
private $entityManager;
private $evalLocker;
public function __construct(EntityManager $em, EvaluationLocker $locker)
{
$this->entityManager = $em;
$this->evalLocker = $locker;
}
public function getName() {
return 'evaluation';
}
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->addEventSubscriber(new EvaluationPageSubscriber($this->evalLocker));
$builder
->add('employeeID', 'text', array(
'label' => 'Employee ID:',
'required' => true,
'trim' => true,
'error_bubbling' => true,
))
->add('managerLogin', 'text', array(
'label' => 'Manager Login:',
'required' => true,
'trim' => true,
'error_bubbling' => true,
'mapped' => false,
))
->add('managerPassword', 'password', array(
'label' => 'Manager Password:',
'required' => true,
'trim' => true,
'error_bubbling' => true,
'mapped' => false,
))
->add('appraisalType', 'choice', array(
'choices' => array('0' => '90 Day', '1' => 'Annual'),
'required' => true,
'expanded' => true,
'multiple' => false,
'label' => 'Appraisal Type:',
'error_bubbling' => true,
))
->add('pages', 'collection');
for($i =0; $i<=$this->evalLocker->getPageCount(); $i++)
{
$page = ($i==0 ? $this->evalLocker->rewind() : $this->evalLocker->next());
if ($page)
{
$builder->get('pages')->add('page_' . $i, new EvaluationPage($page));
}
}
}
}
EvaluationPage (The inner form):
namespace Company\PerformanceBundle\Form\Fields;
use Company\PerformanceBundle\Entity\Noncommitable\EvaluationLockerPage;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class EvaluationPage extends AbstractType {
private $page;
public function __construct( EvaluationLockerPage $page)
{
$this->page = $page;
}
public function getName() {
return 'evaluationPage';
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('bullets', 'collection');
$i =0;
foreach ($this->page as $bullet => $value)
{
if ($bullet)
{
$builder->get('bullets') -> add('bullet_'.$i, 'text', array(
'label' => $bullet,
'data' => $value,
'required' => true,
'trim' => true,
));
}
$i++;
}
}
}
EvaluationLocker and EvaluationLockerPage are simply objects with the ArrayAccess and Iterator interfaces, and a few simple functions such as getPageCount and similar ops.
Think of EvaluationLocker as an array of EvaluationLockerPage arrays. Each EvaluationLockerPage entry is a key/value pair where the key is the bullet point text, and the value is the score it's been assigned.
So, when the page renders, the only bullet point that displays is 'Has a broad and deep understanding of the issues that affect the organization, industry and the business environment.' along with its text box. The rest of the form displays fine, but only that one bullet point is present.
I'm still a little new to Symfony, so if I've done something in a weird way or done something dumb, that's probably why.
What am I missing?