Page 1 of 1

Laugh at how lame this solution is, then advise me.

Posted: Fri Sep 07, 2007 11:15 am
by Luke
I am looking for a good way to catch and display form errors within the zend framework. What I've done, and I know it's lame, is create a couple of view helpers that catch these messages and display them accordingly. I am looking for advice on a better way to do this, since this feels hacky at best. I have been away from PHP development for several months now and I'd say I'm rather rusty. Thanks!

Here are the view helpers I created to do my dirty work:

Code: Select all

<?php

/**
 * Class returns an error message if there is an error for the particular key passed in
 * If no key is passed in, it checks to see if any of the form's elements have an error
 * otherwise it just returns false
 */
class Zend_View_Helper_formError
{
    /**
     * The view object that created this helper object.
     * @var Zend_View
     */
    public $view;

    public function formError($name = null)
    {
        // this next line is here so that if formError() is called without argument,
        // it will return false if there are no errors at all
        if (is_null($name)) return empty($this->view->errorMessages);
        // if the errorMessage array has not been created, create it.
        if (!is_array($this->view->errorMessages)) $this->view->errorMessages = array();
        // return the error message(s) associated with the $named element
        return (array_key_exists($name, $this->view->errorMessages)) ? $this->view->errorMessages[$name] : false;
    }
}

/**
 * This class allows for the controller to set an error for a particular element
 * in my form
 */
class Zend_View_Helper_formSetError
{
    /**
     * The view object that created this helper object.
     * @var Zend_View
     */
    public $view;

    public function formSetError($name, $error)
    {
        // if the error messages array has not been created, create it
        if (!is_array($this->view->errorMessages)) $this->view->errorMessages = array();
        // if the array of messages for this particular element has not been created, create it
        if (!array_key_exists($name, $this->view->errorMessages)) $this->view->errorMessages[$name] = array();
        // set the error for this element
        $this->view->errorMessages[$name][] = $error;
    }
}

/**
 * Class returns the value for a specific form element if there is one,
 * otherwise it returns a blank string
 */
class Zend_View_Helper_formValue
{
    public function formValue($name = null, $get = null)
    {
        $front = Zend_Controller_Front::getInstance();
        $data = (is_null($get)) ? $front->getRequest()->getPost() : $front->getRequest()->getQuery();
        
        return (array_key_exists($name, $data)) ? $data[$name] : '';
    }
}
and the template:

Code: Select all

  <form method="post" action="<?php echo $this->url(array('action' => 'create')); ?>">

    <fieldset id="vendor-info">

      <legend>Vendor Creation</legend>
      
      <?php if ($this->formError()): ?><p class="error">Your form contains some errors. Please check below and fix any errors you see.</p><?php endif; ?>
      
      <div class="meta">
        
        <p class="header">Vendor Creation</p>
      
        <p>Please enter the necessary data to the left. Required elements are denoted by bold text.</p>
      
      </div>

      <dl>
      
        <dt class="required"><label for="vendor_name">Vendor Name</label></dt>
        
        <dd class="<?php if ($this->formError('vendor_name')) echo 'error' ?>">
          
          <div class="message">
            
            <?php if ($this->formError('vendor_name')) echo '<p>' . $this->formError('vendor_name') . '</p>'; ?>
              
            <?php echo $this->formText('vendor_name', $this->formValue('vendor_name')); ?>
              
          </div>
            
        </dd>
      
        <dt><label for="corporate_name">Corporate Name</label></dt>
        
        <dd class="<?php if ($this->formError('corporate_name')) echo 'error' ?>">
          
          <div class="message">
            
            <?php if ($this->formError('corporate_name')) echo '<p>' . $this->formError('vendor_name') . '</p>'; ?>
            
            <?php echo $this->formText('corporate_name', $this->formValue('corporate_name')); ?>
              
          </div>
            
        </dd>
      
      </dl>
        
      <div class="submit clear" style="clear:left"><input type="submit" value="Submit"></div>
        
      <div class="clear"></div>

    </fieldset> <!-- /user-info -->

  </form>
Oh yea, and feel free to laugh at me for forgetting how to write PHP properly. :(

Posted: Fri Sep 07, 2007 11:38 am
by John Cartwright
I would usually avoid as much logic inside your views as possible, so having stuff like

$this->isFormError('fieldname') is kind of ugly to me. I would simply have that method decide to output an error message or report nothing back.

My forms would generally look like

Code: Select all

$this->form('/action', 'name', array(...));

<div id = 'form1'> 
   <?php 
   $this->onError('name', 'Name is required');
   $this->input('name', ... );
   ?>
</div>
This is obviously over simplified.. but I hope you get the picture.

P.S. I'm actually working on small subset of view helpers, if you'd like to collaborate?

Posted: Fri Sep 07, 2007 11:54 am
by Christopher
Zend framework's Controllers and Views are Helper-centric due to their Solar background, so creating a helper for this is probably the way to go for complex stuff. it is where ZF naturally pushes you (unfortunately).

You could also use a Convention in your Views to set a View value and maybe have a shutdown filter perform some magic on it.

Posted: Fri Sep 07, 2007 12:35 pm
by Luke
So as lame as this is, it's not that far off? :(