php - ZF2 - 创建自定义表单 View 助手

标签 php zend-framework2

不久前,Matthew Weier O'Phinney 发布了 this他博客上关于在 Zend Framework 1 中创建复合表单元素的文章。

我试图在 Zend Framewor 2 中为我的自定义库创建相同的元素,但在呈现表单时我无法找到表单 View 助手。

这是我的元素(DateSegmented.php):

<?php

namespace Si\Form\Element;

use Zend\Form\Element;
use Zend\ModuleManager\Feature\ViewHelperProviderInterface;

class DateSegmented extends Element implements ViewHelperProviderInterface
{

    public function getViewHelperConfig(){
          return array( 'type' => '\Si\Form\View\Helper\DateSegment' );
     }

    protected $_dateFormat = '%year%-%month%-%day%';
    protected $_day;
    protected $_month;
    protected $_year;

    /**
     * Seed attributes
     *
     * @var array
     */
    protected $attributes = array(
        'type' => 'datesegmented',
    );

    public function setDay($value)
    {
        $this->_day = (int) $value;
        return $this;
    }

    public function getDay()
    {
        return $this->_day;
    }

    public function setMonth($value)
    {
        $this->_month = (int) $value;
        return $this;
    }

    public function getMonth()
    {
        return $this->_month;
    }

    public function setYear($value)
    {
        $this->_year = (int) $value;
        return $this;
    }

    public function getYear()
    {
        return $this->_year;
    }

    public function setValue($value)
    {
        if (is_int($value)) {
            $this->setDay(date('d', $value))
                 ->setMonth(date('m', $value))
                 ->setYear(date('Y', $value));
        } elseif (is_string($value)) {
            $date = strtotime($value);
            $this->setDay(date('d', $date))
                 ->setMonth(date('m', $date))
                 ->setYear(date('Y', $date));
        } elseif (is_array($value)
            && (isset($value['day']) 
                && isset($value['month']) 
                && isset($value['year'])
            )
        ) {
            $this->setDay($value['day'])
                 ->setMonth($value['month'])
                 ->setYear($value['year']);
        } else {
            throw new Exception('Invalid date value provided');
        }

        return $this;
    }

    public function getValue()
    {
        return str_replace(
            array('%year%', '%month%', '%day%'),
            array($this->getYear(), $this->getMonth(), $this->getDay()),
            $this->_dateFormat
        );
    }
}

这是我的表单 View 助手:

<?php

    namespace Si\Form\View\Helper;

    use Zend\Form\ElementInterface;
    use Si\Form\Element\DateSegmented as DateSegmented;
    use Zend\Form\Exception;

    class DateSegmented extends FormInput
    {
        /**
         * Render a form <input> element from the provided $element
         *
         * @param  ElementInterface $element
         * @throws Exception\InvalidArgumentException
         * @throws Exception\DomainException
         * @return string
         */
        public function render(ElementInterface $element)
        {
            $content = "";

            if (!$element instanceof DateSegmented) {
                throw new Exception\InvalidArgumentException(sprintf(
                    '%s requires that the element is of type Si\Form\Input\DateSegmented',
                    __METHOD__
                ));
            }

            $name = $element->getName();
            if (empty($name) && $name !== 0) {
                throw new Exception\DomainException(sprintf(
                    '%s requires that the element has an assigned name; none discovered',
                    __METHOD__
                ));
            }

            $view = $element->getView();
            if (!$view instanceof \Zend\View\View) {
                // using view helpers, so do nothing if no view present
                return $content;
            }

            $day   = $element->getDay();
            $month = $element->getMonth();
            $year  = $element->getYear();
            $name  = $element->getFullyQualifiedName();

            $params = array(
                'size'      => 2,
                'maxlength' => 2,
            );
            $yearParams = array(
                'size'      => 4,
                'maxlength' => 4,
            );

            $markup = $view->formText($name . '[day]', $day, $params)
                    . ' / ' . $view->formText($name . '[month]', $month, $params)
                    . ' / ' . $view->formText($name . '[year]', $year, $yearParams);

            switch ($this->getPlacement()) {
                case self::PREPEND:
                    return $markup . $this->getSeparator() . $content;
                case self::APPEND:
                default:
                    return $content . $this->getSeparator() . $markup;
            }

            $attributes            = $element->getAttributes();
            $attributes['name']    = $name;
            $attributes['type']    = $this->getInputType();
            $attributes['value']   = $element->getCheckedValue();
            $closingBracket        = $this->getInlineClosingBracket();

            if ($element->isChecked()) {
                $attributes['checked'] = 'checked';
            }

            $rendered = sprintf(
                '<input %s%s',
                $this->createAttributesString($attributes),
                $closingBracket
            );

            if ($element->useHiddenElement()) {
                $hiddenAttributes = array(
                    'name'  => $attributes['name'],
                    'value' => $element->getUncheckedValue(),
                );

                $rendered = sprintf(
                    '<input type="hidden" %s%s',
                    $this->createAttributesString($hiddenAttributes),
                    $closingBracket
                ) . $rendered;
            }

            return $rendered;
        }

        /**
         * Return input type
         *
         * @return string
         */
        protected function getInputType()
        {
            return 'datesegmented';
        }

    }

This question描述了将 View 助手添加为可调用对象,但它已被声明,因为我的自定义库 (Si) 已添加到“StandardAutoLoader”。

最佳答案

好吧,终于弄明白了。

将 Zend/Form/View/HelperConfig.php 复制到自定义库中的相同位置。调整内容以反射(reflect)您的 View 助手。

将以下内容添加到 Module.php 中的事件或 Bootstrap

$app = $e->getApplication();
$serviceManager = $app->getServiceManager();
$phpRenderer = $serviceManager->get('ViewRenderer');

$plugins = $phpRenderer->getHelperPluginManager();
$config  = new \Si\Form\View\HelperConfig;
$config->configureServiceManager($plugins);

用您的自定义命名空间更新“Si”命名空间。

“类已存在”错误实际上归因于我的 View 帮助程序文件顶部的包含。我已将其更新为:

use Zend\Form\View\Helper\FormElement;

use Zend\Form\Element;
use Zend\Form\ElementInterface;
use Zend\Form\Exception;

由于类名重复,我还将 instanceof 语句更新为绝对位置:

if (!$element instanceof \Si\Form\Element\DateSegmented) {

从 ZF1 到 2 的翻译中还有其他错误,但与此问题无关。

关于php - ZF2 - 创建自定义表单 View 助手,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14380986/

相关文章:

php - 在没有 serviceLocator->get() 方式的情况下,ZF2 中新的依赖注入(inject)方式是否更加低效?

Mysql 在插入时检查表中的最后一个条目

php - Zend 框架 2 : multiple routes to one action

php - 如何将php mysql查询重写为nodejs mysql查询

php - 我们如何在不解压缩 PHP 的情况下读取 zip 文件并获取包含的文件或文件夹的信息?

php - 检查目录路径是否以 DIRECTORY_SEPARATOR 结尾

php - PHP 抛出 Facebook SDK 错误 : uncaught curlexception: 28: connect() timed out!

zend-framework2 - ZfcRbac 角色提供者和身份 getRoles()

php - Zend2 fatal error : Class 'Album\ResultSet' not found

php - php上线 fatal error : Call to a member function execute() on a non-object in/public_html/website/index.