1

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


}
4

0 回答 0