How to create form inputs/elements in ZF2

后端 未结 1 1771
不思量自难忘°
不思量自难忘° 2021-02-08 05:28

EDIT : My main question has now become \'How do I get the ServiceManager with the doctrine entity manager into the hands of my form, element, and input classes in some clean way

相关标签:
1条回答
  • 2021-02-08 05:58

    this is my validator, using a static method to inject the entityManager and working with any doctine entity.

    <?php
    
    namespace Base\Validator;
    
    use Traversable;
    use Zend\Stdlib\ArrayUtils;
    use Zend\Validator\AbstractValidator;
    use Doctrine\ORM\EntityManager;
    
    class EntityUnique extends AbstractValidator
    {
        const EXISTS = 'exists';
    
        protected $messageTemplates = array(
            self::EXISTS => "A %entity% record already exists with %attribute% %value%",
        );
    
        protected $messageVariables = array(
            'entity' => '_entity',
            'attribute' => '_attribute',
        );
    
    
        protected $_entity;
        protected $_attribute;
        protected $_exclude;
    
        protected static $_entityManager;
    
        public static function setEntityManager(EntityManager $em) {
    
            self::$_entityManager = $em;
        }
    
        public function getEntityManager() {
    
            if (!self::$_entityManager) {
    
                throw new \Exception('No entitymanager present');
            }
    
            return self::$_entityManager;
        }
    
        public function __construct($options = null)
        {
            if ($options instanceof Traversable) {
                $options = ArrayUtils::iteratorToArray($token);
            }
    
            if (is_array($options)) {
    
                if (array_key_exists('entity', $options)) {
    
                    $this->_entity = $options['entity'];
                }
    
                if (array_key_exists('attribute', $options)) {
    
                    $this->_attribute = $options['attribute'];
                }
    
                if (array_key_exists('exclude', $options)) {
    
                    if (!is_array($options['exclude']) ||
                        !array_key_exists('attribute', $options['exclude']) ||
                        !array_key_exists('value', $options['exclude'])) {
    
                        throw new \Exception('exclude option must contain attribute and value keys');
                    }
    
                    $this->_exclude = $options['exclude'];
                }
            }
    
            parent::__construct(is_array($options) ? $options : null);
        }
    
        public function isValid($value, $context = null)
        {
            $this->setValue($value);
    
            $queryBuilder = $this->getEntityManager()
                ->createQueryBuilder()
                ->from($this->_entity, 'e')
                ->select('COUNT(e)')
                ->where('e.'. $this->_attribute . ' = :value')
                ->setParameter('value', $this->getValue());
    
            if ($this->_exclude) {
    
                $queryBuilder = $queryBuilder->andWhere('e.'. $this->_exclude['attribute'] . ' != :exclude')
                    ->setParameter('exclude', $this->_exclude['value']);
            }
    
            $query = $queryBuilder->getQuery();        
            if ((integer)$query->getSingleScalarResult() !== 0) {
    
                $this->error(self::EXISTS);
                return false;
            }
    
            return true;
        }
    }
    

    ie. i'm using it for theese form elements which are also tested and working fine:

    <?php
    
    namespace User\Form\Element;
    
    use Zend\Form\Element\Text;
    use Zend\InputFilter\InputProviderInterface;
    
    class Username extends Text implements InputProviderInterface
    {
        public function __construct() {
    
            parent::__construct('username');
            $this->setLabel('Benutzername');
            $this->setAttribute('id', 'username');
        }
    
        public function getInputSpecification() {
    
            return array(
                'name' => $this->getName(),
                'required' => true,
                'filters'  => array(
                    array(
                        'name' => 'StringTrim'
                    ),
                ),
                'validators' => array(
                    array(
                        'name' => 'NotEmpty',
                        'break_chain_on_failure' => true,
                        'options' => array(
                            'messages' => array(
                                'isEmpty' => 'Bitte geben Sie einen Benutzernamen ein.',
                            ),
                        ),
                    ),
                ),
            );
        }
    }
    

    When creating a new user

    <?php
    
    namespace User\Form\Element;
    
    use Zend\InputFilter\InputProviderInterface;
    use User\Form\Element\Username;
    
    class CreateUsername extends Username implements InputProviderInterface
    {
        public function getInputSpecification() {
    
            $spec = parent::getInputSpecification();
            $spec['validators'][] = array(
                'name' => 'Base\Validator\EntityUnique',
                'options' => array(
                    'message' => 'Der name %value% ist bereits vergeben.',
                    'entity' => 'User\Entity\User',
                    'attribute' => 'username',  
                ),    
            );
    
            return $spec;
        }
    }
    

    when editin an existing user

    <?php
    
    namespace User\Form\Element;
    
    use Zend\InputFilter\InputProviderInterface;
    use User\Form\Element\Username;
    
    class EditUsername extends Username implements InputProviderInterface
    {
        protected $_userId;
    
        public function __construct($userId) {
    
            parent::__construct();
            $this->_userId = (integer)$userId;
        }
    
        public function getInputSpecification() {
    
            $spec = parent::getInputSpecification();
            $spec['validators'][] = array(
                'name' => 'Base\Validator\EntityUnique',
                'options' => array(
                    'message' => 'Der name %value% ist bereits vergeben.',
                    'entity' => 'User\Entity\User',
                    'attribute' => 'username',
                    'exclude' => array(
                        'attribute' => 'id',
                        'value' => $this->_userId,  
                    ),
                ),    
            );
    
            return $spec;
        }
    }
    
    0 讨论(0)
提交回复
热议问题