2007-10-26 PEARs HTML QuickForm Controller goodness

I'm in the middle of coding up a multi-page wizard-style bunch of PHP pages. The MVC pattern is implicit herein. It looked like it'd be useful to use the PEAR class HTML_QuickForm_Controller. In combination with HTML_QuickForm for the model, this is a pretty powerful business. As the view, the PEAR package HTML_Template_IT is used.

However, it turns out that debugging can be quite painful. Because the controller and the view part are so loosely coupled, it can be troublesome when it doesn't work.

I defined the 'cancel' action besides the default stuff like 'previous' and 'next'. The related class that should be called when the button was pressed, cleared all values from the session.

The cancel button didn't work; instead it just submitted and the controller served up the next step in the wizard. The difference turned out to be as follows:

  $submit[] =& $this->createElement('submit',
      $this->getButtonName('cancel'), "Cancel");    
  $submit[] =& $this->createElement('submit',
      $this->getButtonName('next'), t('Next'));
  $this->addGroup($submit, "submit");

That last line should be:

  $this->addGroup($submit, 'submit', '', ' ', false);

It's really about that last parameter, the false boolean. This generates a button with name _qf_domregform_cancel instead of submit[_qf_domregform_cancel]. Why the controller interprets this differently, I don't know.

But I do know it took a lot of time to find the culprit. Basically what I did, was take the example code, and adapt one page step-by-step to the page that I coded for the website.

That's not my idea of debugging, but I'm not sure how else the bug could've been narrowed down.

Here's another one. In my wizard, the third step is to choose how DNS is set up. It's a radio button that lets the user choose between 'standard' and 'advanced'. My first attempt looked like this:

 $dns1 =  new HTML_QuickForm_radio(null, 's', 'Standard');
 $dns2 = new HTML_QuickForm_radio(null, 'a', 'Advanced');
 $this->addGroup(array($dns1, $dns2), 'DNS_server', "Choose setting for DNS server");

The problem with the above code is that it doesn't remember its setting when the user goes back from step four to step three. The code below will correctly do this:

 $radio[] = &$this->createElement('radio', null, null, 's', 'Standard');
 $radio[] = &$this->createElement('radio', null, null, 'a', 'Advanced');
 $this->addGroup($radio, 'DNS_server', "Choose setting for DNS server");

Now what is the difference? It can't be seen in the HTML source, so I looked at the PHP code but I couldn't see the difference in the five minutes I checked.

My point to all this is that there is more than one way to do the job, but if it's not the correct one, it silently fails without any message.

That makes a developer's job harder.