Setting Up FirePHP with Zend and PHPUnitTest

So FirePHP is a pretty awesome add on for Firefox. Basically I can just send all my error_log(), print, echo etc statements to FireBug’s console window instead of the application output or error log. To set it up, just do the following:

1) Download FireBug and FirePHP for Firefox.

2) In your bootstrap add the following function (if you’re not using functions, just add the code within somewhere before you initialize your front controller.)

protected function _initLog()
// If you don't have this, 99% chance your unit tests are going to explode and be wrong. I haven't investigated thoroughly yet.

$writer = new Zend_Log_Writer_Firebug();
$logger = new Zend_Log($writer);

$profiler = new Zend_Db_Profiler_Firebug('All Database Queries:');

// Check if development env for FirePHP logging (not testing or production)
if(APPLICATION_ENVIRONMENT != 'development'){

Zend_Registry::set('logger', $logger);
Zend_Registry::set('profiler', $profiler);

3) To start logging, just call the following in your application code

Zend_Registry::get('logger')->log('Hello FirePHP', Zend_Log::INFO);

Step 3 gets skipped in the production and testing environments.

Simple Backtrace

I have an object that emails me whenever an error occurs in an application with user information, sql statement, etc. Usually I can tell where the error is coming from, but by just adding the following lines of code to my script, I now get a complete back trace of the bug!

[code lang=”php”]

$trace = debug_backtrace();

Getting PHPUnit To Run On Local Windows Machine From Remote Server

So I’ve got PHPUnit installed on our development server, but I don’t want to log into the server every time that I want to run a test. To do this locally, I need to change the PHP.ini file settings before PHP ran PHPUnit. The reason for this is because on the development server PHP is installed at C:PHP5 but this directory doesn’t exists on my local machine, so when I open up the command line and do the following:


I get ‘”C:PHP5.php.exe”‘ is not recognized as an internal or …

The reason for this is because if you look in the phpunit.bat file you’ll see that it sets the PHPBIN path to C:PHP5.php.exe so you’re computer is going to look there, no buneo. The trick is to make your computer look for all related PHP files on the server. There are probably a variety of ways to do this but what I did was the following:

1) Since I didn’t want to mess around changing the values in phpunit.bat and phpunit I just wrote a script that would bypass phpunit.bat by running PHP with custom specified include_path and extension_dir

\pathToServerPHP5php -d extension_dir="\pathToServerPHP5ext" -d include_path="\pathToServerPHP5pear; ... ; ." \pathToServerPHP5phpunit TestFile"

2) Since the web root of my applications vary and I need to run the test files from within the public domain of the application, I just wrote a batch script to ask me where the web root is and where the test file is:

@echo off
set /p website="Web root path to application (starts in publicaccess): "
set /p testfile="Where is the PHP Test file located (starts in UnitTests): "
set /p options="Additional PHPUnit options: "
pushd \pathToServerpublicDomain%website%
\pathToServerPHP5php -d extension_dir="\pathToServerPHP5ext" -d include_path="\pathToServerPHP5pear; ... ; ." \pathToServerPHP5phpunit TestFile" %options% \pathToServerUnitTests%testfile%

Mantis 1.2.0 and Automatic Notices (Reminder.php)

This expands on the emailing problem that I was having with Mantis.

I just had the most terrible time setting up an auto reminder with Mantis (Mantis is a bug tracking software) and a user contributed mailing reminder script (

I’m using IIS 6 and PHP 5.3

Step 1 – Using the correct configuration function:

You need to open up reminder.php and change all of the following to use db_get_table instead of config_get

$t_user_table = config_get( 'mantis_user_table' );
$t_project_table = config_get( 'mantis_project_table' );

// In bug_get_assign_date()
$t_bug_history_table = config_get( 'mantis_bug_history_table' );
$t_bug_table = config_get( 'mantis_bug_table' );

// In user_get_assigned_bug
$t_bug_table = config_get('mantis_bug_table');

// In user_get_not_assigned_bug
$t_bug_table = config_get( 'mantis_bug_table' );

Comment out the following

// in the first for loop of user_get_not_assigned_bug
lang_push( user_pref_get_language( $row['id'] ) );

// in the second for loop of user_get_not_assigned_bug
lang_push( user_pref_get_language( $t_user_id ) );

// In email_build_bug_info()
$t_result = diff_date( $t_now_time, unixtimestamp($t_assign_date );

if( $t_result == config_get( 'first_remind' ) && bug_ok_to_send( $p_user_id, $p_bug_id ) ) {
return $t_message;
} else {
if( $t_result >= config_get( 'second_remind' ) && date_ok_to_send( $p_user_id, $p_bug_id ) ) {
return $t_message;
} else {
return '';

Near the end of reminder.php (past line 300) change
$t_email_send = email_send( $t_send_email , $t_subject, $t_message);


$t_email_send = email_send((object) array('email' => $t_send_email , 'subject' => $t_subject, 'body' => $t_message));

This still leaves some warnings about some lang_get() values not getting found, but I get the emails now so that’s all that I cared about.

Write / Read Custom Data – Zend_Session_SaveHandler_DbTable

I couldn’t find this anywhere so I’ll post it here. When storing information with sessions you sometimes might want to keep a user id, real user name, etc as part of the session. To accomplish this using Zend and a session database table:

1) Set up the database:

2) To save custom data:

// Create the table adapter and then authenticate the login.
$adapter = $this->getAuthAdapter($db, $this->view->form->getValues());
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($adapter);

// If a successful login, store custom session data into the session table's datacolumn.
if($result->isValid()) {
$results = $adapter->getResultRowObject(array('id', 'username', 'firstname', 'lastname'));
$mysession = new Zend_Session_Namespace('mysession');
$mysession->id = $results->id;
$mysession->username = $results->username;
$mysession->firstname = $results->firstname ;
$mysession->lastname = $results->lastname ;

3) To get the custom data:

$mysession = new Zend_Session_Namespace('mysession');
echo $mysession ->id;
echo $mysession ->username;
echo $mysession ->firstname;
echo $mysession ->lastname;

Creating A Dynamic Grouped Form Element

So a common thing that I’ve always done in my forms is create a group of inputs that can be dynamically created again (through JS). For example I would allow users to add N number of contacts. To add a new one the user would click on “add” and JS would do its DOM creation and add all the new elements with name=”myname[]”. I wanted to do this with Zend and still have the JS generated content reshow up on a form submission. I’ve searched forever on how to do this, so hopefully this helps someone. (It’s probably not the best way, but it does work.)

These two tutorial helped greatly: (custom elements) (ajax)

Form HTML to reproduce:

The Person Element Class:


parent::__construct($spec, $options);
$this->_fnameID = parent::getID().'FirstName';
$this->_lnameID = parent::getID().'LastName';
$this->_emailID = parent::getID().'Email';

public function loadDefaultDecorators()
if ($this->loadDefaultDecoratorsIsDisabled()) {
$decorators = $this->getDecorators();
if (empty($decorators)) {
->addDecorator('Description', array(
'tag' => 'p',
'class' => 'description')
->addDecorator('HtmlTag', array(
'tag' => 'ul',
'id' => $this->getName())

protected function getDecoratorName(){
return 'Person';

public function getLabel($type){

case 'firstName':
return $this->getFirstNameLabel();
case 'lastName':
return $this->getLastNameLabel();
case 'email':
return $this->getEmailLabel();
else {
return parent::getID();
// throw new Exception('Please choose a label.');


public function getID($type){

case 'firstName':
return $this->getFirstNameID();
case 'lastName':
return $this->getLastNameID();
case 'email':
return $this->getEmailID();
else {
return parent::getID();
// throw new Exception('Please choose a label.');


public function getFirstNameID(){
return $this->_fnameID;

public function getFirstNameLabel(){
return $this->_fnameLabel;

public function setFirstName($value){
$this->_fname = $value;
return $this;

public function getFirstName(){
return $this->_fname;

public function getLastNameID(){
return $this->_lnameID;

public function getLastNameLabel(){
return $this->_lnameLabel;

public function setLastName($value){
$this->_lname = $value;
return $this;

public function getLastName(){
return $this->_lname;

public function getEmailID(){
return $this->_emailID;

public function getEmailLabel(){
return $this->_emailLabel;

public function setEmail($value){
$this->_email = $value;
return $this;

public function getEmail(){
return $this->_email;

public function setValue($values){
if(isset($values['firstName']) && isset($values['lastName']) && isset($values['emailName'])){
else {
// What till validation, could add it here?
; //throw new Exception('Invaild Person, please provide a first name, last name and email.');

return $this;

public function getValue(){
return $this->getFirstName().' '.$this->getLastName().', '.$this->getEmail();


The People Decorator class:


public function render($content){
$el = $this->getElement();
if(!$el instanceof My_Form_Element_Person){
return $content;

$view = $el->getView();
if(!$view instanceof Zend_View_Interface){
return $content;
$markup = $this->wrap($this->renderFirstName($el).$this->renderLastName($el).$this->renderEmailName($el));

switch ($this->getPlacement()) {
case self::PREPEND:
return $markup . $this->getSeparator() . $content;
case self::APPEND:
return $content . $this->getSeparator() . $markup;

protected function renderFirstName($el){
return $this->renderEl('firstName', $el->getFirstName(), $el);

protected function renderLastName($el){
return $this->renderEl('lastName', $el->getLastName(), $el);

protected function renderEmailName($el){
return $this->renderEl('email', $el->getEmail(), $el);

protected function renderEl($type, $value, $el){
$name = $el->getFullyQualifiedName();
return sprintf($this->_format, $el->getID($type), $el->getLabel($type), $el->getID($type), $name.'['.$type.']', $value);

protected function wrap($markup) { return '

  • '.$markup.'
  • '; }

    Here is the DynamicController that handles the AJAX JS creation:

    $ajaxContext = $this->_helper->getHelper('AjaxContext');
    $ajaxContext->addActionContext('newfield', 'html')->initContext();

    $id = $this->_getParam('id', null);

    $element = new My_Form_Element_Person('person');

    // What is returned thru ajax
    $this->view->field = $element->__toString();

    My JS script (I use prototype) You can see how to do it with JQuery from on of the above tutorials:

    Event.observe('addElement', 'click',
    function() {
    // Get value of id - integer appended to dynamic form field names and ids
    var id = $("id").getValue();
    // Retrieve new element's html from controller
    function ajaxAddField() {

    // Update the database based on the Primary key with the new value.
    new Ajax.Request('/apply/index.php/dynamic/newfield',
    method: 'post',
    parameters: {'id':'id='+id},
    onSuccess: function(el){
    // Increment and store id


    The prevalidation method (in your Form class) that captures the dynamic content on submit:

    public function preValidation(array $data) {
    // Search $data for dynamically added fields using findFields callback
    $fnames = $data['person']['firstName'];
    $lnames = $data['person']['lastName'];
    $emails = $data['person']['email'];

    // For each person
    $this->persons[] = $el;
    // Used to redisplay the new content.
    public function getPersons(){

    $els = $this->persons;
    $xhtml = '';
    foreach($els as $el => $e){
    $xhtml .= $e->__toString(); // Add HTML
    return $xhtml;

    In my main view I display all of the people by:

    form->getPersons() ?>

    For the newField action you need a viewscript with:

    field ?>

    That’s all of the pieces. If I get time better I’ll try to explain how to put them together. Please read this tutorial first, it will help you set up the AJAX stuff. Then just add a button element and a container and everything should work.

    What do you think??

    Zend_Form – Submitting Without MVC

    There was a time when I didn’t use MVC…

    class ContactForm extends Zend_Form {
    public function __construct($options = null) {


    $contact_name = new Zend_Form_Element_Text('contact_name');
    $contact_name->setLabel('Contact Name: ')

    $submit = new Zend_Form_Element_Submit('submit');

    $this->addElements(array($contact_name, $submit));

    public function setView(Zend_View_Interface $view) {

    // Render each form element.
    foreach ($this as $item) {
    return $this;
    if (isset($_POST['submit'])) {
    // Get the form object.
    $form = unserialize($_SESSION['myForm']);
    if ($form->isValid($_POST)) {
    echo 'success';
    // Not valid, so populate the form with the sent values.
    else {
    else {
    // Need to keep a handle on the form (I think Zend does this internally if you use the MVC approach)
    $form = new ContactForm();
    $_SESSION['myForm'] = serialize($form);
    // Display your form.
    echo $form->render(new Zend_View());