Zend_Form: addElementPrefixPath против addPrefixPath - PullRequest
1 голос
/ 26 января 2012

В настоящее время я создаю свой собственный набор элементов формы с помощью Zend_Form и хочу, чтобы все мои элементы в моей пользовательской форме могли использовать мои собственные декораторы

Итак, я создал пользовательскую форму, подобную этой:

<?php
class Nuke_Form extends Zend_Form
{

    public function __construct($options = null)
    {
        $this->addElementPrefixPath('Nuke_Form_Decorator_TwitterBootstrap', 'Nuke/Form/Decorator/TwitterBootstrap/', 'decorator');

        parent::__construct($options);

    }

}

И ради полноты, это мой Декоратор

<?php
class Nuke_Form_Decorator_TwitterBootstrap_ControlGroup extends Zend_Form_Decorator_Abstract
{

    public function render($content)
    {
        $class = $this->getOption('class') ?: "control-group";

        $element = $this->getElement();
        $errors = $element->getMessages();
        if (!empty($errors)) {
            $class .= " error";
        }

        $output = '<div class="' . $class . '">' . $content . '</div>';

        return $output;
    }

}

и конкретная реализация формы, которую я создаю в моих контроллерах

class App_Form_Index_Test extends Nuke_Form
{
    public function init()
    {
        parent::init();

        $this->addAttribs(array('class' => 'form-horizontal'));

        $username = new Nuke_Form_Element_Text('username');
        $username->setLabel("Gebruikersnaam")
                 ->setDescription("This is a description")
                 ->setRequired(true)
                 ->addValidator('NotEmpty', true)
                 ->addValidator('int');

        $submit = new Zend_Form_Element_Submit('submit');

        $this->addElements(array($username, $submit));
    }
}

Но по какой-то причине Элементы не могут найти Декораторы и выдают следующее исключение:

Message: Plugin by name 'ControlGroup' was not found in the registry; used paths: Zend_Form_Decorator_: Zend/Form/Decorator/

Анализируя исключение, я вижу, что мой путь к плагину не добавлен, хотя я добавил его явно, используя addElementPrefixPath () в классе Nuke_Form.


Странно то, что когда я добавляю PluginPath к каждому из моих пользовательских элементов в отдельности, он работает безупречно, как показано ниже.

<?php
class Nuke_Form_Element_Text extends Zend_Form_Element_Text
{
    public function init()
    {
        $this->addPrefixPath('Nuke_Form_Decorator_TwitterBootstrap', 'Nuke/Form/Decorator/TwitterBootstrap/', 'decorator');

        $this->addDecorators(array(
            array('ViewHelper', array(
                'helper' => 'formText'
            )),
            array('Errors'),
            array('Description', array(
                'placement' => Zend_Form_Decorator_Abstract::APPEND,
                'class' => 'help-block'
            )),
            array(array('controls' => 'HtmlTag'), array(
                'tag'   => 'div',
                'class' => 'controls',
            )),
            array('Label', array(
                'class' => 'control-label',
                'requiredSuffix' => ' *',
                'placement' => Zend_Form_Decorator_Abstract::PREPEND
            )),
            array('ControlGroup')
        ));
    }
}

Я использую последнюю версию Zend Framework (v1.11.11).

После некоторого исследования я заметил, что addElementPrefixPath () добавит путь ко всем добавленным элементам формы при вызове, я думаю, именно поэтому он не будет работать при вызове его в конструкторе Nuke_Form, поскольку в то время ни один элемент не имел был добавлен еще. Но как мы должны использовать этот метод тогда? Я нашел несколько примеров в сети, которые с успехом вызывают его в конструкторе. Я озадачен или что-то упускаю из виду.

Ответы [ 2 ]

2 голосов
/ 26 января 2012

попробуйте передать его в конструкторе:
$options = array('elementPrefixPath' => 'Nuke/Form/Decorator/TwitterBootstrap/');

или, возможно, поместите его в init ():

public function __construct($options = null)
{
    parent::__construct($options);

}
public function init() {
    $this->addElementPrefixPath('Nuke_Form_Decorator_TwitterBootstrap_', 'Nuke/Form/Decorator/TwitterBootstrap/', 'decorator');
}

}

Я думаю, что вызов в init () будет работать лучше. И не стесняйтесь вызывать parent::init(); здесь, это просто пустая функция в Zend_Form, нечего переопределять.

ЭТО РАБОТАЕТ

Я использовал весь ваш код, кроме пользовательского элемента, я установил elementPrefixPath в inti () и вызвал ControlGroup Decorator, используя addDecorator () вместо обычного Zend_Form_Element, это вывод:

<form enctype="application/x-www-form-urlencoded" class="form-horizontal" method="post" action=""><dl class="zend_form">
<div class="control-group"><dt id="username-label"><label for="username" class="required">Gebruikersnaam</label></dt>
<dd id="username-element">
<input type="text" name="username" id="username" value="" />
<p class="description">This is a description</p></dd></div>
<dt id="submit-label">&#160;</dt><dd id="submit-element">
<input type="submit" name="submit" id="submit" value="submit" /></dd></dl></form>

единственное изменение, которое я сделал, - добавление в префикс завершающего _ .

<?php
class Application_Form_NukeForm extends Zend_Form
{

    public function __construct($options = null)
    {

        parent::__construct($options);

    }
    public function init(){
        $this->addElementPrefixPath('Jgs_Decorator_', '/Jgs/Decorator/', 'decorator');
    }

}

Конечно, я использовал свой собственный путь ...

<?php
class Application_Form_Test extends Application_Form_NukeForm
{
    public function init()
    {
        parent::init();

        $this->addAttribs(array('class' => 'form-horizontal'));

        $username = new Zend_Form_Element_Text('username');
        $username->setLabel("Gebruikersnaam")
                 ->setDescription("This is a description")
                 ->setRequired(true)
                 ->addValidator('NotEmpty', true)
                 ->addValidator('int')
                ->addDecorator('ControlGroup');

        $submit = new Zend_Form_Element_Submit('submit');

        $this->addElements(array($username, $submit));
    }
}

Я только переименовал декоратор, чтобы соответствовать моему пути

<?php
class Jgs_Decorator_ControlGroup extends Zend_Form_Decorator_Abstract
{

    public function render($content)
    {
        $class = $this->getOption('class') ?: "control-group";

        $element = $this->getElement();
        $errors = $element->getMessages();
        if (!empty($errors)) {
            $class .= " error";
        }

        $output = '<div class="' . $class . '">' . $content . '</div>';

        return $output;
    }

}

Я думаю, что ваша проблема в другом ...
Я также получил __constructor для работы, мне пришлось настроить параметры, чтобы получить правильные параметры:

<?php

class Application_Form_NukeForm extends Zend_Form {

    public function __construct($options = array('elementPrefixPath' => array(
            'prefix' => 'Jgs_',
            'path' => '/Jgs/',
            'type' => 'decorator'
    ))) {

        parent::__construct($options);
    }

Я очень надеюсь, что это поможет:)

0 голосов
/ 27 января 2012

в class Nuke_Form_Element_Text вам может быть лучше, если вы вызовете setDecorators () вместо addDecorators (), так как кажется, что вы заменяете все декораторы по умолчанию.Вы также можете просто добавить $this->loadDefaultDecoratorsIsDisabled();

...