You could create a custom decorator.
App_Form_Decorator_AdditionalError
extends Zend_Form_Decorator_Abstract
{
protected $_options = array(
'additionalError' => 'ERROR'
);
public function render( $content )
{
$element = $this->getElement();
if( $element->isErrors() )
{
$element->addError( $this->getOption( 'additionalError' ) );
}
return $content;
}
}
But this would only push an additional error to the stack of errors. You could get more fancy by actually prepending or appending the error to the $content in stead of simply adding it with addError(). (And perhaps extend the HtmlTag decorator in stead of the Abstract decorator). But I'm to lazy to make complete example of that right now. Sorry. Maybe I'll get back to this tomorrow. Hope this helps/inspires you nonetheless.
BTW; usage of the above would be:
$this->setDecorators(array(
array(
'AdditionalError',
array( 'additionalError' => 'Some additional error message' )
)
'FormErrors',
// etc.
Edit:
Alright, so I had a good nights sleep, and here is a better suggestion. It extends Desciption to take advantage of already defined options, like tag, escape etc. It's even translatable (yay!! :) ). And this one adds a setError option and overrides the render method. It is untested though, so you might get some bugs, and/or syntax errors.
class App_Form_Decorator_AdditionalError
extends Zend_Form_Decorator_Description
{
protected $_error = 'error';
public function setError( $error )
{
$this->_error = (string) $error;
return $this;
}
public function getError()
{
if( null !== ( $error = $this->getOption( 'error' ) ) )
{
$this->setError( $error );
$this->removeOption( 'error' );
}
return $this->_error;
}
public function render( $content )
{
$element = $this->getElement();
$view = $element->getView();
if( !$element->isErrors() || null === $view )
{
return $content;
}
$error = $this->getError();
$error = trim( $error );
if( !empty( $error ) && ( null !== ( $translator = $element->getTranslator() ) ) )
{
$error = $translator->translate( $error );
}
if( empty( $error ) )
{
return $content;
}
$separator = $this->getSeparator();
$placement = $this->getPlacement();
$tag = $this->getTag();
$class = $this->getClass();
$escape = $this->getEscape();
$options = $this->getOptions();
if( $escape )
{
$error = $view->escape( $error );
}
if( !empty( $tag ) )
{
require_once 'Zend/Form/Decorator/HtmlTag.php';
$options[ 'tag' ] = $tag;
$decorator = new Zend_Form_Decorator_HtmlTag( $options );
$error = $decorator->render( $error );
}
switch( $placement )
{
case self::PREPEND:
return $error . $separator . $content;
case self::APPEND:
default:
return $content . $separator . $error;
}
}
}
Usage:
public function init()
{
$this->addPrefixPath( 'App_Form', 'App/Form' ); // or any other namespace you will use
$this->setDecorators( array(
'FormErrors',
'FormElements',
array(
'AdditionalError',
array( 'error' => 'You messed up! :)', 'placement' => 'prepend', 'tag' => 'div', 'class' => 'additional-error' )
),
array(
'HtmlTag',
array( 'tag' => 'dl', 'class' => 'zend_form' )
),
'Form'
) );
}
Edit 2:
I've tested it now, and removed syntax errors and bugs. Seems to be working as expected now.