Wednesday, June 10, 2009

CakePHP Flex and the CpAmf Plugin

Been trying to dive into more RIA development by learning Flex. In the process, I came across the following articles:

Flex remoting with cakePHP - CpAmf plugin

CpAmf Flex Example

In this article it talks about VO (Value-Object) mapping. I was able to download the demo and get it all working great. However, when I tried to tackle this myself in my own application, I came up frustrated. The reason for this frustration was that apparently I don't read very well. In the article from The Bakery it indicated the following.


In our model we create an afterFilter method, and use the cakePHP built in Set::Map() function to convert the associative array to an object (or array of objects). We use generic class here (php's dummy class 'stdClass'), set the _explicitType property of all objects, and unset the _name_ property (which is set by Set::Map() method), because we don't need this property in our flex class. This approach allows us to change the model, and the corresponding flex class without the need for changing the vo classes (we don't even need to create them).


Well, after two days of fooling around with my controller to make this work, I ended up digging into the Model code from the demo project and found this little snippet:


function afterFind( $results )
{
//Convert the results to objects
$resultObjects = Set::map( $results );
foreach ( $resultObjects as &$item )
{
// Set _explicitType for all objects,
// for correct mapping the object in flex
$item->_explicitType = $this->name;

// We does not need the _name_ property, which is set automatically
// by the Set::Map() function when we use it without a class name
unset ( $item->_name_ );

}

return $resultObjects;
}


Had I been reading the original article correctly, I would not have wasted all this time trying to figure this out.

1 comment:

  1. for some reason setting the _explicitType inside the loop hasn't work for me for associated models, so I ended up removing the whole loop from the method, and added a new field called _explicitType to the database with the classname as default value I wanted :)

    also tweaked the controllers like this:
    function index()
    {

    $this->constructClasses();
    if( $this->RequestHandler->requestedWith( "amf" ) )
    {
    return $this->Jersey->find( 'all' );
    }
    else
    {
    $this->set( 'jerseys', $this->Jersey->find( 'all' ) );
    }
    }

    to be able to use it both for amf and plain html.

    ReplyDelete