Zend Framework: Form Plain Text

AttachmentSize
ZExt_Form_Element_PlainText.php1.09 KB
ZExt_View_Helper_FormPlainText.php1.79 KB

I had several hacks in place in various Zend Framework based project for outputting plain text on a form and decided at long last to work from within the system again. The only solution that made sense to me was to create a Zend_Form_Element_Xhtml object that output as its value plain escaped text. Decorators can be added in the normal way to remake this control in as many forms as one might wish.

The path to the view helper for this control will need to be registered with something like the following in the bootstrap; note that I'm using "ZExt" as the library name here (as in "Zend-Extended") which is just an arbitrary name I've selected for the sake of example:

<?php
. . .
// Initialise Zend_Layout's MVC helpers
Zend_Layout::startMvc();
. . .
Zend_Layout::getMvcInstance()->getView()->addHelperPath('ZExt/View/Helper/', 'ZExt_View_Helper');
. . .

An example call to this function might look something like this:

<?php
. . .
$someForm->addElement(new ZExt_Form_Element_PlainText('someFieldName', array(
  'value'=>$someValue,
)));
. . .
// output text surrounded by table header cell tags:
$someTableForm->addElement(new ZExt_Form_Element_PlainText('someFieldName', array(
  'decorators'=>array(
    'ViewHelper',
    array('HtmlTag', array('tag' => 'th')),
  ),
  'value'=>$someValue,
)));

Aaaaaand the ZExt_Form_Element_PlainText class itself; note that this is more-or-less just a pointer to a helper as is the convention with Zend Framework's form elements. Also, thanks to a note from Ryan King (see the comments on this page), the isValid() function is overridden here to always return true; PlainText elements are always "valid", and failing validation causes issues.

<?php
/**
 * @category   ZExt
 * @package    ZExt_Form
 * @subpackage ZExt_Form_Element
 * @author     Sean P. O. MacCath-Moran
 * @email      zendcode@emanaton.com
 * @website    http://www.emanaton.com
 * @copyright  This work is licenced under a Attribution Non-commercial Share Alike Creative Commons licence
 * @license    http://creativecommons.org/licenses/by-nc-sa/3.0/us/
 *
*/
    
/** Zend_Form_Element_Xhtml */
require_once 'Zend/Form/Element/Xhtml.php';
    
/**
 * Plain text form element
 *
 * @category   ZExt
 * @package    ZExt_Form
 * @subpackage ZExt_Form_Element
 * @author     Sean P. O. MacCath-Moran
 * @email      zendcode@emanaton.com
 * @website    http://www.emanaton.com
 * @copyright  This work is licenced under a Attribution Non-commercial Share Alike Creative Commons licence
 * @license    http://creativecommons.org/licenses/by-nc-sa/3.0/us/
*/
class ZExt_Form_Element_PlainText extends Zend_Form_Element_Xhtml {
  /**
   * Default form view helper to use for rendering
   * @var string
  */
  public $helper = 'formPlainText';

  public function isValid($value){
    return true;
  }
}

Finally, the class that does all the heavy lifting (he said with just a smidgen of sarcasm) along with another bug fix from Ryan King (he said with sincere gratitude):

<?php
/**
 * @category   ZExt
 * @package    ZExt_View
 * @subpackage ZExt_View_Helper
 * @author     Sean P. O. MacCath-Moran
 * @email      zendcode@emanaton.com
 * @website    http://www.emanaton.com
 * @copyright  This work is licenced under a Attribution Non-commercial Share Alike Creative Commons licence
 * @license    http://creativecommons.org/licenses/by-nc-sa/3.0/us/
 *
*/
    
/**
 * Abstract class for extension
 */
require_once 'Zend/View/Helper/FormElement.php';
    
/**
 * Helper to generate a "plaintext" element
 *
 * @category   ZExt
 * @package    ZExt_View
 * @subpackage ZExt_View_Helper
 * @author     Sean P. O. MacCath-Moran
 * @email      zendcode@emanaton.com
 * @website    http://www.emanaton.com
 * @copyright  This work is licenced under a Attribution Non-commercial Share Alike Creative Commons licence
 * @license    http://creativecommons.org/licenses/by-nc-sa/3.0/us/
*/
class ZExt_View_Helper_FormPlainText extends Zend_View_Helper_FormElement {
  /**
   * Generates text.
   *
   * @access public
   *
   * @param string|array $name If a string, is set as the "value" and rendered. The
   * real "value" setting will take precidence if set. In effect, the "name" value
   * become the default for "value" when "value" is not set. If an array, all other
   * parameters are ignored, and the array elements are extracted in place of added
   * parameters.
   *
   * @param mixed $value The element value.
   *
   * @param array $attribs Attributes for the element tag.
   *
   * @return string The element XHTML.
  */
  public function formPlainText($name, $value = null, $attribs = null) {
    $info = $this->_getInfo($name, $value, $attribs);
    extract($info); // name, value, attribs, options, listsep, disable
    if (null === $value) {$value = $name;}
    
    return $this->view->escape($value);
  }
}

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

overwriting escape-function

Hey Rian,

this additional form element is nearly what i was looking for. Only problem, i would like to inject markup but it will be escaped through htmlspecialchars. do you have an idea how to change escape function of Zend_View_Abstract?

regards Boris

Zero Values

If I may make a further suggestion, the view helper checks $value to make sure the PlainText element has some value. I believe a better check instead of:

<?php if (!$value) {$value = $name;} ?>

would be:

<?php if ($value === NULL) {$value = $name;} ?>

During my tests, my zero (0) value PlainText elements were not displaying properly.

Re: Zero Values

Greetings Ryan King,

Zero evaluating to false in PHP?! Who ever HEARD of such a thing?!

I'm actually a little embarrased at having had that particular bug out there as I'm always getting on my peer about proper type checking in their PHP conditionals. *sigh* -- but that's the price of having one's code public, eh?

Thanks again, Ryan!

Regards,

Sean P. O. MacCath-Moran
www.emanaton.com

Solved: This function does not work properly

NOTE: Edited by Sean P. O. MacCath-Moran on 16 Dec 09: Added PHP formatting.

After spending some time digging through the Zend Framework, I believe this function does actually work properly. The problem is that the default implementation of the Zend_Form_Element's function, isValid, does not work properly.

When using PlainText elements, there is no respective element in the form post data itself. During $form->isValid, this code is run:

foreach ($this->getElements() as $key => $element) {
    if (!isset($data[$key])) {
        $valid = $element->isValid(null, $data) && $valid;
    } else {
        $valid = $element->isValid($data[$key], $data) && $valid;
    }
}

where $data is the post data and $key is the form element's name loaded from Zend_Form you've defined. Since there is no element name submitted in the post data to match the PlainText element present in the form, null is passed to the $element->isValid() function.

I'm unsure why this is done, but the $element->isValid function takes the following actions right at the beginning:

      $this->setValue($value);
      $value = $this->getValue();

IMO, isValid should only return the result of the element's validation. Why is it setting the value during validation? I'm going to submit this as a bug to Zend.

Upon further thought, this functionality may actually be desirable. If you're validating and there is a validation error, you will most likely redisplay the form for correction. This code will pre-fill the elements with the previously submitted post data so users won't have to retype it. But, this functionality is not appropriate for isValid and we can see how it creates a problem in this instance.

There are a couple solutions I considered. One would be to adapt PlainText to include a hidden variable of the same name and value. But this isn't really the point or purpose of the PlainText element.

I ended up overloading the isValid function for the Zend_Form_Element_PlainText.

Change this:

class Zend_Form_Element_PlainText extends Zend_Form_Element_Xhtml
{
    /**
     * Default form view helper to use for rendering
     * @var string
     */
    public $helper = 'formPlainText';
}

to this:

class Zend_Form_Element_PlainText extends Zend_Form_Element_Xhtml
{
    /**
     * Default form view helper to use for rendering
     * @var string
     */
    public $helper = 'formPlainText';

    public function isValid($value){
        return true;
    }
}

All PlainText elements are valid by default. There is nothing submitted for that element during a post so isValid should always return true for PlainText elements.

Ryan King
CEO
Quark Creative Design, LLC
quarkcreativedesign.com

Re: Solved: This function does not work properly

Greetings Ryan,

I've had this on my to-do list to investigate, but your evaluation and solution are sound and well considered, and so you have spared me that task. Thank you VERY much! I've integrated your solution into the original post.

Regards,

Sean P. O. MacCath-Moran
www.emanaton.com

This function does not work properly

I dont think this works properly in a form. To clarify when the form is first present every thing is fine, but it gets validate the returned form does not contain the plain text information

Great Help

Thanks a lot, this is exactly what I needed.
Great Explanation!

Thanks a lot, this i

Thanks a lot, this is exactly what I needed.
Great Explanation!
network monitoring

Great

Thanks for the code - exactly what i searched for hours and hours.

Re: Great

Greetings,

Well - I'm glad you found it, but I'm sorry it took so long to find. I'll have to see where this page land on the SEO side of things.

Regards,

Sean P. O. MacCath-Moran
www.emanaton.com

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.