我是 ZF2 和 Doctrine2 的新手。
我想知道,我可以将字段集用于在表单中重复的类似元素吗?同一个形式可能有几个相似的元素,并且有许多相似的形式。
这些元素映射到实体中的常规字段(没有一对多或多对一关系),并且同一实体中有更多字段。
如果可能的话,我该如何为这样的字段集设置对象?
我收到以下错误:
Zend\Hydrator\Exception\BadMethodCallException
File:
D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-hydrator\src\ArraySerializable.php:26
Message:
Zend\Hydrator\ArraySerializable::extract expects the provided object to implement getArrayCopy()
Stack trace:
#0 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-form\src\Fieldset.php(631): Zend\Hydrator\ArraySerializable->extract(Object(OnlineFieldEvaluation\Entity\CompetencyDemonstrateEthicalAndProfessionalBehavior))
#1 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-form\src\Form.php(944): Zend\Form\Fieldset->extract()
#2 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-form\src\Form.php(303): Zend\Form\Form->extract()
#3 D:\wamp\www\onlinefieldevaluation\module\OnlineFieldEvaluation\src\OnlineFieldEvaluation\Controller\TabsController.php(170): Zend\Form\Form->bind(Object(OnlineFieldEvaluation\Entity\CompetencyDemonstrateEthicalAndProfessionalBehavior))
#4 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-mvc\src\Controller\AbstractActionController.php(82): OnlineFieldEvaluation\Controller\TabsController->editTabAction()
#5 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#6 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-eventmanager\src\EventManager.php(490): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#7 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-eventmanager\src\EventManager.php(263): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#8 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-mvc\src\Controller\AbstractController.php(118): Zend\EventManager\EventManager->triggerEventUntil(Object(Closure), Object(Zend\Mvc\MvcEvent))
#9 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-mvc\src\Controller\Plugin\Forward.php(143): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#10 D:\wamp\www\onlinefieldevaluation\module\OnlineFieldEvaluation\src\OnlineFieldEvaluation\Controller\OnlineFieldEvaluationController.php(845): Zend\Mvc\Controller\Plugin\Forward->dispatch('OnlineFieldEval...', Array)
#11 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-mvc\src\Controller\AbstractActionController.php(82): OnlineFieldEvaluation\Controller\OnlineFieldEvaluationController->showStudentEvaluationAction()
#12 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#13 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-eventmanager\src\EventManager.php(490): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#14 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-eventmanager\src\EventManager.php(263): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#15 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-mvc\src\Controller\AbstractController.php(118): Zend\EventManager\EventManager->triggerEventUntil(Object(Closure), Object(Zend\Mvc\MvcEvent))
#16 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-mvc\src\DispatchListener.php(114): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#17 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#18 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-eventmanager\src\EventManager.php(490): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#19 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-eventmanager\src\EventManager.php(263): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#20 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-mvc\src\Application.php(340): Zend\EventManager\EventManager->triggerEventUntil(Object(Closure), Object(Zend\Mvc\MvcEvent))
#21 D:\wamp\www\onlinefieldevaluation\public\index.php(27): Zend\Mvc\Application->run()
#22 {main}
这是我到目前为止所尝试的:
工厂示例
<?php
class FIGradeFSFactory implements FactoryInterface
{
protected $options = array();
protected $name;
public function __construct( array $options = array())
{
$this->options = $options['options'];
$this->name = $options['name'];
}
public function createService(ServiceLocatorInterface $formElementManager)
{
$elementName = $this->options["select_element_name"];
$name = $this->getName();
$options = $this->getOptions();
return new FIGradeFS($name, $options);
}
.......... Getters and Setters
}
字段集示例
<?php
namespace OnlineFieldEvaluation\Form;
class FIGradeFS extends Fieldset implements ObjectManagerAwareInterface, InputFilterProviderInterface, EventManagerAwareInterface
{
protected $objectManager;
protected $name;
protected $commentName;
protected $options;
protected $events;
protected $entityName;
/**
* @param ObjectManager $objectManager
*/
public function __construct($name = null, $options = array())
{
$this->name = $name;
$fsName = $name."FS";
parent::__construct($fsName, $options);
$this->commentName = $name . "Comment";
$this->options = $options;
$this->entityName = $options['allowed_object_binding_class'];
}
/**
*
*/
public function init()
{
$figrade = $this->name;
$figradeComment = $figrade . 'Comment';
$om = $this->getObjectManager();
$hydrator = new DoctrineHydrator($om, $this->entityName);
$hydrator->addStrategy($figrade , new FiGradeFSStrategy($figrade, $this->entityName));
$hydrator->addStrategy($figradeComment , new FiGradeFSStrategy($figradeComment, $this->entityName));
$this->setHydrator($hydrator)->setObject( new $this->entityName());
$options = $this->getOptions();
$tabPosition = $options["tabPosition"];
$qtnLetter = $options["qtnLetter"];
$isNA = $options["isNA"];
$this->add(array(
'name' => $figrade,
// 'type' => 'Zend\Form\Element\Select',
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'attributes' => array(
'required' => 'required',
'class' => 'fi-grade',
),
'options' => array(
'label' => 'Field Instructor Grade',
'object_manager' => $om,
'target_class' => $this->entityName,
'disable_inarray_validator' => true,
'property' => $figrade,
'value_options' => $this->getOptionsForSelect($isNA, $tabPosition, $qtnLetter),
),
));
//Comment popup
$this->add(array(
'type' => 'Zend\Form\Element\Textarea',
'name' => $figradeComment,
'attributes' => array(
'id' => $figradeComment,
),
'options' => array(
'label' => 'FI Comment',
),
));
}
/**
* @return array
*/
public function getInputFilterSpecification()
{
return array(
$this->name => array(
'required' => false,
),
$this->commentName => array(
'required' => false,
),
);
}
............... other methods..........................
}
实体示例:
<?php
/**
* OnlineFieldEvaluation - ${FILE_NAME}
*
* Initial version by: Viktor
* Initial version created on: 4/23/15
*/
namespace OnlineFieldEvaluation\Entity;
// Add these import statements
use Doctrine\ORM\Mapping as ORM;
/**
* An Identity Information.
*
* @ORM\Entity
* @ORM\Table(name="form_comp_advance_rights_justice")
*
**/
class CompetencyAdvanceHumanRightsAndJustice extends CompetencyBase
{
/**
* @ORM\Column(type="string", length=10)
*/
protected $applJusticeFIGrade;
/**
* @ORM\Column(type="string", length=1000)
*/
protected $applJusticeFIGradeComment;
/**
* @ORM\Column(type="string", length=10)
*/
protected $applJusticeSSGrade;
/**
* @ORM\Column(type="string", length=10)
*/
protected $engageJusticeFIGrade;
/**
* @ORM\Column(type="string", length=1000)
*/
protected $engageJusticeFIGradeComment;
/**
* @ORM\Column(type="string", length=10)
*/
protected $engageJusticeSSGrade;
/**
* CompetencyAdvanceHumanRightsAndJustice constructor.
*/
public function __construct()
{
//calculate summary grade
// $this->calculateFiSummaryGrade();
}
public function getAllFiGrades()
{
$fiGrades[] = null;
if ($this->applJusticeFIGrade != null)
$fiGrades[] = $this->applJusticeFIGrade;
if ($this->getEngageJusticeFIGrade() != null)
$fiGrades[] = $this->engageJusticeFIGrade;
return $fiGrades;
}
...... setters and getters
}
表格示例:
<?php
/**
* OnlineFieldEvaluation - ${FILE_NAME}
*
* Initial version by: Viktor
* Initial version created on: 4/23/15
*/
namespace OnlineFieldEvaluation\Form;
use Zend\Captcha;
use Zend\Form\Element;
class CompetencyAdvanceHumanRightsAndJusticeForm extends BaseCompetencyForm
{
/**
* @param null $name
* @param null $options
*/
public function __construct($name = null, $options = null)
{
parent::__construct($name, $options);
}
/**
* needs to be set in init(), because constructor won't be aware of objectmanager
*/
public function init()
{
$this->setAttribute('method', 'post');
$this->getBaseCompetencyFormElements();
$this->add($this->getCaptionElement('applJustice'));
// Add the a fieldset for FI grade of appJustice
$this->addFIGrade('applJusticeFIGrade', $this->getTabPosition(), 'a', 'OnlineFieldEvaluation\Entity\CompetencyAdvanceHumanRightsAndJustice');
$this->add(array(
'name' => 'applJusticeSSGrade',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'required' => 'required',
),
'options' => array(
'label' => 'Student Self Grade',
'disable_inarray_validator' => true,
'value_options' => $this->getOptionsForSelect($this->getSemester(), $this->getTabPosition(), 'a'),
),
));
$this->add($this->getExampleText('applJusticeFBExample'));
$this->add($this->getExampleText('applJusticeVFPExample'));
$this->add($this->getCaptionElement('engageJustice'));
//Add FIGrade
$this->addFIGrade('engageJusticeFIGrade', $this->getTabPosition(), 'b', 'OnlineFieldEvaluation\Entity\CompetencyAdvanceHumanRightsAndJustice');
$this->add(array(
'name' => 'engageJusticeSSGrade',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'required' => 'required',
),
'options' => array(
'label' => 'Student Self Grade',
'disable_inarray_validator' => true,
'value_options' => $this->getOptionsForSelect($this->getSemester(), $this->getTabPosition(), 'b'),
),
));
$this->add($this->getExampleText('engageJusticeFBExample'));
$this->add($this->getExampleText('engageJusticeVFPExample'));
parent::init();
}
public function getAllCompetencyNamesForForm()
{
return array(
'applJustice',
'engageJustice',
);
}
}
基础能力表格:
<?php
/**
* OnlineFieldEvaluation - formFileName
*
* Initial version by: Viktor
* Initial version created on: 7/16/15
*/
namespace OnlineFieldEvaluation\Form;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use OnlineFieldEvaluation\Strategy\FIGradeFSStrategy;
use Zend\Form\Element;
use Zend\Form\Form;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
abstract class BaseCompetencyForm extends Form implements ObjectManagerAwareInterface, ServiceLocatorAwareInterface, SignatureAwareInterface
{
protected $captionService;
/**
* @var
*/
private $semester;
/**
*
* @var
*/
protected $serviceLocator;
/**
* @var \Doctrine\ORM\EntityManager
*/
private $objectManager;
private $name;
private $buildName;
private $tabName;
private $tabPosition;
protected $options;
protected $isSigned;
protected $isNA;
protected $role;
/**
* @param null $name
* @param null $options
*/
public function __construct($name = null, $options = null)
{
$this->name = $name;
$this->options = $options;
parent::__construct($name, $options);
$this->semester = $options['semester'];
$this->buildName = $options['buildName'];
$this->tabPosition = $options['tabPosition'];
$this->tabName = $options['tabName'];
$this->isSigned= $options['isSigned'];
$this->isNA = $options['isNA'];
$this->role = $options['role'];
}
/**
*
*/
public function init()
{
$om = $this->getObjectManager();
$this->setAttribute('name', $this->getName());
$this->setAttribute('class', 'competency-form');
$hydrator = new DoctrineHydrator($om);
// $hydrator->setObject($this->getEntityInstanceFromBuildName($this->buildName));
// $hydrator->addStrategy('applJusticeFIGradeFS', new FiGradeFSStrategy());
$entityName = 'OnlineFieldEvaluation\Entity\\' . $this->buildName;
foreach ($this->getAllCompetencyNamesForForm() as $compName) {
$figrade = $compName . 'FIGrade';
$figradeComment = $figrade . 'Comment';
// $hydrator->addStrategy($figrade, new FiGradeFSStrategy($figrade, $entityName));
// $hydrator->addStrategy($figradeComment, new FiGradeFSStrategy($figradeComment, $entityName));
// TODO: Here Apply captionService
// $competencyCaption = $compName.'Caption';
//
// $hydrator->addStrategy($competencyCaption, new AssignCaptionsStrategy($competencyCaption, $entityName));
}
// $this->setHydrator($hydrator);
// disable elements if the form is signed
if($this->isSigned)
{
$this->disableElements($this->getIterator());
}
}
/**
* @param $formElements
*/
protected function disableElements($formElements)
{
foreach ($formElements as $elementOrFieldset) {
if ($elementOrFieldset instanceof \Zend\Form\FieldsetInterface) {
$fsElements = $elementOrFieldset->getIterator();
$this->disableElements($fsElements);
} else {
$elementOrFieldset->setAttribute('disabled', 'disabled');
}
}
}
/**
* @param $name
* @return mixed
*/
protected function getCaptionElement($name)
{
$formElementManager = $this->serviceLocator;
$options = [
'name' => $name,
'type' => 'CompetencyElementCaption',
'shared' => false,
'attributes' => array(
'class' => 'competency-task',
'disabled' => 'disabled',
'required' => 'required',
),
'options' => array(
'label' => 'test label'
),
];
$captionElement = $formElementManager->get('CompetencyElementCaption', $options);
// $captionElement->setOptions($options);
return $captionElement;
}
/**
* @param $name
* @return mixed
*/
protected function getExampleText($name)
{
$formElementManager = $this->serviceLocator;
$options = [
'name' => $name,
'type' => 'CompetencyExampleText',
'shared' => false,
'attributes' => array(
'class' => 'competency-task',
'disabled' => 'disabled',
'required' => 'required',
),
'options' => array(
'label' => 'test label'
),
];
$exampleTextElement = $formElementManager->get('CompetencyExampleText', $options);
// $captionElement->setOptions($options);
return $exampleTextElement;
}
/**
*
*/
private function getEntityInstanceFromBuildName($buildName)
{
$entityName = 'OnlineFieldEvaluation\Entity\\' . $buildName;
return new $entityName();
}
/**
*
*/
public function getBaseCompetencyFormElements()
{
$this->add(array(
'name' => 'id',
// 'type' => 'Hidden',
'options' => array(
'label' => 'ID',
),
));
$this->add(array(
'type' => 'Hidden',
'name' => 'tabName',
'attributes' => array(
'value' => $this->tabName
)
));
$this->add(array(
'type' => 'Hidden',
'name' => 'buildName',
'attributes' => array(
'class' => 'build-name',
'value' => $this->buildName
)
));
$this->add(array(
'type' => 'Hidden',
'name' => 'semester',
'attributes' => array(
'value' => $this->semester
)
));
$this->add(array(
'type' => 'Hidden',
'name' => 'tabPosition',
'attributes' => array(
'value' => $this->tabPosition,
),
));
$this->add(array(
'type' => 'Hidden',
'name' => 'isSigned',
'attributes' => array(
'value' => $this->isSigned,
),
));
$this->add(array(
'name' => 'studEvalId',
'type' => 'Hidden',
'options' => array(
'label' => 'Student Evaluation ID',
),
));
$this->add(array(
'type' => 'Hidden',
'name' => 'fiSummaryGrade',
'attributes' => array(
'class' => 'grades-summary',
'label' => 'FI Summary Grade',
)
));
$this->add(array(
'name' => 'csrf',
'type' => 'Zend\Form\Element\Csrf',
'options' => array(
'csrf_options' => array(
'timeout' => 7200
)
)
));
$this->add(array(
'name' => 'submitbutton',
'type' => 'Submit',
'attributes' => array(
'value' => 'Save',
'id' => 'submitbutton',
),
'options' => array(
'label' => 'Save It',
),
));
}
/**
* @param mixed $semester
*/
public function setSemester($semester)
{
$this->semester = $semester;
}
/**
* @return mixed
*/
public function getSemester()
{
return $this->semester;
}
/**
* @param $semester
* @return array
*/
public function getOptionsForSelect($semester, $tabPosition, $qtnLetter)
{
$question = ($tabPosition - 1) . $qtnLetter;
$naQuestions = array('3a', '3b', '4b', '5a', '5b', '5c', '8c', '9a', '9b', '9c');
$valueOptions = null;
// if ($semester === 1 && in_array($question, $naQuestions)) {
if ($this->isNA === true && in_array($question, $naQuestions)) {
$valueOptions = array(
'na' => 'N/A',
'0' => '0',
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4',
'5' => '5',
'6' => '6',
'7' => '7',
'8' => '8',
'9' => '9',
'10' => '10',
);
} else {
$valueOptions = array(
'0' => '0',
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4',
'5' => '5',
'6' => '6',
'7' => '7',
'8' => '8',
'9' => '9',
'10' => '10'
);
}
return $valueOptions;
}
/**
* @return mixed
*/
public function getObjectManager()
{
return $this->objectManager;
}
/**
* @param ObjectManager $objectManager
* @return $this
*/
public function setObjectManager(ObjectManager $objectManager)
{
$this->objectManager = $objectManager;
// return $this;
}
/**
* @param ServiceLocatorInterface $sl
*/
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
/**
* @return mixed
*/
public function getServiceLocator()
{
return $this->serviceLocator;
}
/**
* @param null $name
* @param null $bindingClass
* @return mixed
*/
protected function addFIGrade($name = null, $tabPosition = null, $qtnLetter = null, $bindingClass = null)
{
// $options = $this->getFIFieldSetOptions($name, $this->getSemester(), $tabPosition, $qtnLetter, $bindingClass);
$isNA = $this->getIsNA();
$options = $this->getFIFieldSetOptions($name, $isNA, $tabPosition, $qtnLetter, $bindingClass);
$formElementManager = $this->serviceLocator;
$fieldset = $formElementManager->get('FIGradeFS', array('name' => $name, 'options' => $options));
$this->add($fieldset);
}
/**
* @param null $name
* @param array $options
*/
protected function getFIFieldSetOptions($name = null, $isNA = 0, $tabPosition = null, $qtnLetter = null, $bindingClass = null)
{
return array(
'use_as_base_fieldset' => false,
'object_manager' => $this->getObjectManager(),
'disable_inarray_validator' => true,
'allowed_object_binding_class' => $bindingClass,
'select_element_name' => $name,
// 'semester' => $semester,
'isNA' => $isNA,
'tabPosition' => $tabPosition,
'qtnLetter' => $qtnLetter
);
}
/**
* @param null $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @return null
*/
public function getName()
{
return $this->name;
}
/**
* @param null $options
*/
public function setOptions($options)
{
$this->options = $options;
}
/**
* @return null
*/
public function getOptions()
{
return $this->options;
}
/**
* @param mixed $buildName
*/
public function setBuildName($buildName)
{
$this->buildName = $buildName;
}
/**
* @return mixed
*/
public function getBuildName()
{
return $this->buildName;
}
/**
* @param mixed $tabPosition
*/
public function setTabPosition($tabPosition)
{
$this->tabPosition = $tabPosition;
}
/**
* @return mixed
*/
public function getTabPosition()
{
return $this->tabPosition;
}
/**
* Order matters in this function
*/
abstract public function getAllCompetencyNamesForForm();
/**
* @param $isSigned
*/
public function setIsSigned($isSigned)
{
$this->isSigned = $isSigned;
}
/**
* @return mixed
*/
public function getIsSigned()
{
return $this->isSigned;
}
/**
* @return mixed
*/
public function getIsNA()
{
return $this->isNA;
}
/**
* @param mixed $isNA
*/
public function setIsNA($isNA)
{
$this->isNA = $isNA;
}
}