Home » Featured, Software

toArray() with Doctrine 2 and Zend Forms.

24 November 2010 2,865 views 4 Comments

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;
}

4 Comments »

  • david said:

    Hi there,
    I’d like to use your functionnality.
    However i don’t understand how to implement it.

    Can you detail this part please ?
    “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”

    What abstract class?
    What class to extend? Entity\Manager?
    How ?

    Best regards

    David

  • Neal (author) said:

    Hi David,

    The abstract class in this case is base class that all of your entities will use.. as an example, given:

    vehicle.php
    – car.php
    – truck.php
    – van.php
    – etc..

    .. where you were to keep all of your common functionality in the base class “vehicle” and extend / implement specifics for each type of vehicle.. example:

    class truck extends vehicle {
    // specific 'truck' things go here..
    }

    .. so vehicle.php is your base class and contains the toArray() method… so you can call:

    $t = new truck();
    $t->toArray();

    ..follow?

    - Neal

  • Marcin said:

    This it will be work only if we have in Our model magical methods (if we have private properties in Entities):

    /**
    * __get Magic method for get Object attributes
    * @param $property
    */
    public function __get($property)
    {
    return $this->$property;
    }
    /**
    * __set Magic method for set property and value
    * @param $property
    * @param $value
    */
    public function __set($property, $value)
    {
    $this->$property = $value;
    }

  • venimus said:

    i put that in a clasthe repository
    filter($method));

    $name = \preg_replace(‘/^get_/ui’, ”, $filtered);
    $value = $object->{$method}();
    if (!is_object($value)) {
    $q[$name] = $value;
    }
    }
    }
    }else if (is_array($object)){
    $q=$object;
    }
    return \array_map(‘\Repositories\objectToArray’, $q);
    }

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.