Jiří Knesl

Na hlavní stranu

Event-driven Zend_Form

Po experimentování s frameworkem Nette jsem si oblíbil event-driven přístup k formulářům. Proto jsem zde pro své čtenáře připravil jednoduchý způsob, jak jednoduchý přístup k formulářům implementovat i v Zend_Form.

Rešení není zcela dokonalé, mezi hlavní nevýhody patří to, že je nápad omezen na jednoduchý výčet několika Zend_Form_Elementů, zatímco Vy si mužete elementu, které mužou zpusobit submit, nadefinovat nekonečno. Další problém, na který jsem narazil, byl v Zend_Registry v metodě offsetExists, kde jsem musel explicitne přetypovat $this na pole (return array_key_exists($index, (Array)$this);). Testováno na PHP 5.3.0alpha3-dev a Zend Frameworku 1.7.0.

Tak zde je kód:


set_include_path("library" . PATH_SEPARATOR . get_include_path());

require "Zend/Form.php";
require "Zend/View.php";

class MyForm extends Zend_Form
{

  /**
   * @param string|Array $callback
   * @param string $name   
   * @return mixed   
   */     
  public function onClick($callback, $name)
  {
    $post = $_POST;

    if (! array_key_exists($name, $post) || ! in_array($name, $post))
      return false;

    if (! $this->isValid($post))
      return false;  
  
    $element = $this->getElement($name);    
    $type = $element->getType();
  
    $types  = array(
      "Zend_Form_Element_Submit", 
      "Zend_Form_Element_Input",
      "Zend_Form_Element_Button",
      "Zend_Form_Element_Image"
    );
    if (in_array($type, $types))
      return call_user_func($callback, $this);
    else
      return false;      
  }
  
  /**
   * @param string|Array $callback
   * @return mixed   
   */     
  public function onSubmit($callback)
  {
    $post = $_POST;

    $found = false;
    $elements = $this->getElements();
    foreach ($elements as $element)
    {
      if (array_key_exists($element->getName(), $post))
        $found = true;
    }
    
    if (! $found)
      return false;

    if ( !$this->isValid($post))
      return false;  

    $elements = $this->getElements();
    foreach ($elements as $element)
    {
      if (! array_key_exists($element->getName(), $post))
        continue;
    
      $type = $element->getType();
      $types  = array(
        "Zend_Form_Element_Submit", 
        "Zend_Form_Element_Input",
        "Zend_Form_Element_Button",
        "Zend_Form_Element_Image"
      );
      if (in_array($type, $types))
          return call_user_func($callback, $this);
      }
    return false;
  }

}


function submit1_click(MyForm $form)
{
  $text = $form->getElement("text")->getValue();
  echo "submit1_click: {$text}<br />";
}

function submit2_click(MyForm $form)
{
  $text = $form->getElement("text")->getValue();
  echo "submit2_click: {$text}<br />";
}

function myform_submit(MyForm $form)
{
  $text = $form->getElement("text")->getValue();
  echo "myform_submit: {$text}<br />";
}


$form = new MyForm;

$form->addElement("text", "text", array("required"=>true));
$form->addElement("submit", "submit1");
$form->addElement("submit", "submit2");
$form->addElement("submit", "submit3");

$form->onClick("submit1_click", "submit1");
$form->onClick("submit2_click", "submit2");
$form->onSubmit("myform_submit");

echo $form->render(new Zend_View);

Jak můžete vidět, celé je to velmi jednoduché. Již jsem tento přístup (mírně obměněný) použil i v praxi a skutečně se mi osvědčil.

Další proti: Při ukládání pravděpodobně použijete $form->getValues(), která ale prožené funkci definovanými filtry, takže hodnoty, které budete validovat, se mohou lišit.

Nahoru