不久前,Matthew Weier O'Phinney在他的博客上发表了关于在Zend Framework 1中创建复合表单元素的文章。{/ p>
我正在尝试在Zend Framewor 2中为我的自定义库创建相同的元素,但在渲染表单时我遇到了查找表单视图助手的问题。
这是我的元素(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
);
}
}
这是我的表单视图助手:
<?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描述了将视图助手添加为可调用的,但它已经被声明,因为我的自定义库(Si)已添加到'StandardAutoLoader'。
答案 0 :(得分:1)
好的,最终想出了这个。
将Zend / Form / View / HelperConfig.php复制到自定义库中的相同位置。调整内容以反映您的视图助手。
将以下内容添加到Module.php
中的事件或引导程序中$app = $e->getApplication();
$serviceManager = $app->getServiceManager();
$phpRenderer = $serviceManager->get('ViewRenderer');
$plugins = $phpRenderer->getHelperPluginManager();
$config = new \Si\Form\View\HelperConfig;
$config->configureServiceManager($plugins);
使用您的自定义命名空间更新'Si'命名空间。
“类已经存在”错误实际上是我视图帮助文件顶部的包含错误。我已将其更新为:
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的翻译还有其他错误,但它们与此问题无关。
答案 1 :(得分:0)
我理解您的代码的方式是:您正在创建新的Form\Element
以及新的Form\View\Helper
。在这种情况下,您需要以下信息:
StandardAutoloader
只负责实际查找类。 invokables
内的getViewHelperConfig()
声明就在那里,因此框架知道调用Class
时要加载的ViewHelper
。
在你的情况下,你这样做:
public function getViewHelperConfig()
{
return array(
'invokables' => array(
'dateSegmented' => 'Si\Form\View\Helper\DateSegmented'
)
);
}
Zend Framework 2为/Zend/Form/View/HelperConfig.php
内部的ViewHelpers
做了此事