toArray() with Doctrine 2 and Zend Forms.

Based on a couple of assumptions (like ‘NS’ is your library that handles the Doctrine Entity Manager) ..in your abstract class, will need 2 methods:

/**
 *  A way to force eager loading.
 */
public function forceEagerLoad() {
    return true;
}

/**
 * Returns the object and its properties as an array.
 */
public function toArray() {
    $tmpMergedMappings = array();
    $tmpFieldMappings = array();
    $tmpAssocMappings = array();
    if(!$this->em) { $this->em = NS::em(); }
    $testObj = $this->em->find(get_class($this), $this->id);
    $testJob = $testObj->job;
    $tmpFieldMappings = $this->em->getClassMetadata(get_class($this))->fieldMappings;
    $tmpAssocMappings = array_keys($this->em->getClassMetadata(get_class($this))->associationMappings);
    foreach($tmpFieldMappings as $fmKey => $fmValue) {
        if(is_object($this->$fmKey)) {
            if (get_class($this->$fmKey) == "DateTime" ) {
                switch ($tmpFieldMappings[$fmKey]["type"]) {
                    case "sndatetype":
                        $tmpMergedMappings[$fmKey] = $this->$fmKey->format('m/d/Y');
                        break;
                    // handle any custom types..
                    default:
                        $tmpMergedMappings[$fmKey] = $this->$fmKey->format('Y-m-d H:i:s');
                        break;
                }
            } else {
                // presume the default _id mapping...
                $key_id = $fmKey."_id";
                $tmpMergedMappings[$key_id] = $this->$key_id->id;
            }
        } else {
            $tmpMergedMappings[$fmKey] = $this->$fmKey;
        }
    }
    foreach($tmpAssocMappings as $amKey => $amValue) {
        $tmpKey = $amValue."_id";
        switch (get_class($this->$amValue)) {
            case "Doctrine\ORM\PersistentCollection":
                // dont do anything with these right now..
                break;
            default:
                // Trigger the loading via the proxy.
                if(method_exists($this->$amValue, 'forceEagerLoad')) {
                    $forced = $this->$amValue->forceEagerLoad();
                } else {
                    // Note: these classes dont have/inherit a forceEagerLoad() method,
                    // or we are trying to call it on something not set yet.
                    //var_dump(get_class($this->$amValue));
                    //var_dump($amValue);
                }
                if($this->$amValue) {
                    if($this->$amValue->id != null) {
                        $tmpMergedMappings[$tmpKey] = $this->$amValue->id;
                    }
                }
            break;
        }
    }
    return $tmpMergedMappings;

}

..and then in your Zend Controller action, say for editing:

/**
 *
 */
public function editAction() {
    $id = $this->getRequest()->getParam('id');
    $role = $this->em->find('NS\Role', $id);
    if(empty($role)) {
        // handle error
        return $this->_helper->redirector->gotoUrl('/role');
    } else {
        $this->view->role = $role;
        $this->view->form = $this->roleForm($role->toArray());
    }
}

..and your form can look something like this:

/**
*
*/
public function roleForm($data = null) {
    $form = new Zend_Form();
    $form->setAction($this->view->baseUrl().'/role/create')->setMethod('post');
    // id (hidden)
    $id = new Zend_Form_Element_Hidden('id');
    $id->removeDecorator('Label');
    $id->removeDecorator('HtmlTag');
    $form->addElement($id);
    // name
    $name = new Zend_Form_Element_Text('name');
    $name->setLabel('Name');
    $name->setRequired(true)->addValidator('NotEmpty');
    $form->addElement($name);
    // description
    $description = new Zend_Form_Element_Text('description');
    $description->setLabel('Description');
    $description->setRequired(true)->addValidator('NotEmpty');
    $form->addElement($description);
    // submit button
    $submit = new Zend_Form_Element_Submit('Save');
    $form->addElement($submit);
    if($data) {
        $form->setDefaults($data);
        $form->populate($data);
    }
    return $form;
}