Object-relational mapping with Doctrine, Flash Builder, and PHP

Richard Bates @ Zend Developer Zone wrote a good article on my favorite ORM Doctrine integration in Zend;

Rich Internet applications built with Adobe Flex and Flash Builder have been steadily gaining a foothold in enterprise development for quite some time. As the platform has grown and evolved, PHP has also made amazing progress toward becoming a mature, powerful object-oriented language with rapid adoption and dozens of frameworks and design pattern implementations. As PHP continues to prosper, developers are able to borrow more and more of the things Java has got right, taking one check after another from the “Java-only” column. One outstanding example of this is object-relational mapping (ORM). A few different PHP ORM implementations are available, and all of them have positive attributes. However, after some experimentation, I’ve found that Doctrine is my favorite.

Read the complete story;

Object-relational mapping with Doctrine, Flash Builder, and PHP.

Automate Db Model Creation with Zend_CodeGenerator_Php_Class

Joey Rivera wrote a very interesting and time saving article about the Zend_CodeGenerator complete with a easy to use code snippet that will create the model and DbTable files and classes for you, as it picks the information directly from your database, it’s no way those pesky typos and cut and paste mistakes creep in when you have to do 10 (or 300) almost identical files.

Worth checking out; Joey’s Blog

Console ProgressBar and Text

The query was; How to set the Text Label on the progressbar in console mode.
The answer by Michael “Ray” Rehbein: You want to set the ‘elements’ option of the adapter.

http://framework.zend.com/manual/en/zend.progressbar.html#zend.progressbar.adapter.console


$pbAdapter = new Zend_ProgressBar_Adapter_Console(
array('elements'=>
array(Zend_ProgressBar_Adapter_Console::ELEMENT_PERCENT,
Zend_ProgressBar_Adapter_Console::ELEMENT_BAR,
Zend_ProgressBar_Adapter_Console::ELEMENT_ETA,
Zend_ProgressBar_Adapter_Console::ELEMENT_TEXT)
)
);

$progressBar = new Zend_ProgressBar($pbAdapter, 0, 10);

for ($i = 0; $i < 10; $i++) {
sleep(1);
$progressBar->update($i, "Iteration: {$i}"); } $progressBar->finish();
}

Quite nifty.

Custom Flash Messenger for Zend Framework

Mohammed Alsharaf wrote a good working example; FlashMessenger is an action helper in Zend Framework used to pass messages for the users on the next request.
Thats all good, but what about presenting the messages for the users? how to store different type of messages, System, Error, or Success messages?
To achive my goal, i have built two classes, one is an action helper and the other one is view helper.

Action Helper Class

This action helper class act as a factory and singleton pattern. It store the messages in different namespaces of the flash messenger. You can also, retrieve a namesapce by its key to add another message.


/**
* @author Mohammed Alsharaf
* @category Core
* @package Core_ActionHelper
* @copyright Copyright (c) 2008-2009 Mohammed Alsharaf.
* @license http://framework.zend.com/license/new-bsd
*/
class Core_ActionHelper_Messenger extends Zend_Controller_Action_Helper_Abstract
{
protected $_flashMessenger = null;

public function messenger($name='error',$message=null) {
if($name == 'error' &amp;amp; $message === null) {
return $this;
}
if(!isset($this->_flashMessenger[$name])) {
$this->_flashMessenger[$name] = $this->getActionController() ->getHelper('FlashMessenger') ->setNamespace($name.'_message');
}
if($message !== null) {
$this->_flashMessenger[$name]->addMessage($message);
}
return $this->_flashMessenger[$name];
}

public function direct($name='error',$message=null) {
return $this->messenger($name,$message);
}
}

View Helper Class

The view helper loops all the namespaces of the flash messenger and render the messages using the htmlList view helper

/**
* @author Mohammed Alsharaf
* @category Core
* @package Core_ViewHelper
* @copyright Copyright (c) 2008-2009 Mohammed Alsharaf.
* @license http://framework.zend.com/license/new-bsd
*/
class Core_ViewHelper_Messenger extends Zend_View_Helper_Abstract
{
protected $_messageKeys = array(
'msg_message',
'error_message',
'info_message',
'success_message',
'warning_message',
);

public function messenger()
{
foreach($this->_messageKeys as $messageKey) {
if($messages = $this->_getMessages($messageKey)) {
echo $this->_renderMessage($messages,$messageKey);
}
}
}

protected function _getMessages($messageKey)
{
$result = array();
$flashMessenger = Zend_Controller_Action_HelperBroker::getStaticHelper('FlashMessenger');
$flashMessenger->setNamespace($messageKey);

if($flashMessenger->hasMessages()) {
$result = $flashMessenger->getMessages();
}

// check view object
if(isset($this->view->$messageKey)) {
array_push($result, $this->view->$messageKey);
}

//add any messages from this request
if ($flashMessenger->hasCurrentMessages()) {
$result = array_merge($result,
$flashMessenger->getCurrentMessages()
);
//we don’t need to display them twice.
$flashMessenger->clearCurrentMessages();
}
return $result;
}

protected function _renderMessage($message, $name)
{
if(!is_array($message)) {
$message = array($message);
}
return $this->view->htmlList($message, false, array('class'=>$name), true);
}
}

Usage:

In your controller to add a message for the next request

// option one
$this->_helper->messenger('success',"Your message is here.");
// another option to add message
$this->_helper->messenger('success')->addMessage('Your message is here.');

To add a message in the current view:

$this->view->info_message = 'stiky message for the current view';

In your layout file add the following, so if there are messages to view, the helper will print them.

<div id="messages"><?php $this->messenger(); ?></div>

Update:
Carlton Gibson over at noumenal also have a very nice tutorial and view helper that you might want to look at.
http://blog.noumenal.co.uk/2009/08/using-zend-framework-flashmessenger.html

Cloud computing with PHP – Using Amazon EC2 with the Zend Framework

Doug Tidwell is a senior software engineer in IBM’s Emerging Technology group. He just wrote a two part article on Moving data into and out of the cloud with the Zend Framework and Using virtual machines with the Zend Framework.

Summary: The Zend Framework contains several classes that make using cloud-based storage services easy.

Part 1 and Part 2.

Cloud computing with PHP, Part 2: Using Amazon EC2 with the Zend Framework

Converting your Zend Framework MVC application into an XML webservice using one single plugin

Thijs Feryn writes an excellent article on how to convert your entire MVC app or one or more controllers into a XML service. I actually have this one in a production environment and it works like a charm.

That’s right folks, in this blog post I’ll show you how you can convert your entire MVC application into a REST-style XML webservice. And I’m not talking about refactoring tons of code … NO, we’ll plug this option in without changing a single thing to your action controllers.

This post will contain a detailed description of the concepts used. The source could of the plugin is also shown and finally how it will look like when using it.

The concept

Thanks to those lovely hooks in Zend Framework you can simply intervene in nearly every aspect of the MVC workflow. The image below shows you the workflow.

Zend Controller Basics

Zend Controller workflow The hooks I’m talking about are actually just methods that are called by the plugin broker system. They already exist as empty methods in the Zend_Controller_Plugin_Abstract which we inherit from. So we override them in order to hook into the MVC flow.

Alle information on Zend Framework plugins can be found in the reference pages. A lot of you Zend Framework experts will now say: “why don’t you just use the context switching action helper?”. I could have done that, but this requires modifying your application. This post is about plugging it in, remember?

How am I doing it then? Well … I hook into the workflow at “post dispatch” time, this means that de dispatcher has already processed al controllers and is about to send all about back to the browser by using a Zend Controller Response object.

Before the front controller sends the output back to the browser, we empty the output’s body and add our own content. This content is retrieved from the view object which would normally parse and render the view object. The view has a set of properties which are set by the controllers. I use the reflection API to get a hold of all these items. Finally I serialize them and output it all.

The plugin


<?php
/**
* My_Plugin_Xml component
* Turns an Zend Framework MVC website into an XML webservice
*/
/**
* My_Plugin_Xml class
*
* @author Thijs Feryn <[email protected]>
*/
class My_Plugin_Xml extends Zend_Controller_Plugin_Abstract
{
/**
* Stores the front controller
*
* @var Zend_Controller_Front
*/
private $_front;
/**
* Stores the XML output in DOMDocument format
*
* @var DOMDocument
*/
private $_xml;
/**
* Class constructor
*/
public function __construct()
{
$this->_front = Zend_Controller_Front::getInstance();
$layout = Zend_Layout::getMvcInstance();
$layout->disableLayout();
}
/**
* Build DOMDocument to convert output to XML
*
* @param mixed $return
* @param Exception $exception
* @return string
*/
private function _getXML($return = null,Exception $exception = null)
{
$this->_xml = new DOMDocument('1.0', 'UTF-8');
$this->_xml->formatOutput = true;

$responseNode = $this->_xml->createElement('response');

$exceptionNode = $this->_xml->createElement('exception');
if(null !== $exception && $exception == instanceof( Exception ){
$exceptionNode->appendChild(
$this->_xml->createElement('message',
$exception->getMessage()
)
);
$exceptionNode->appendChild(
$this->_xml->createElement('code',
$exception->getCode()
)
);
$exceptionNode->appendChild(
$this->_xml->createElement('type',
get_class($exception)
)
);
}

$responseNode->appendChild($exceptionNode);
if(null !== $return){
$responseNode->appendChild(
$this->_serialize('return',$return)
);
} else {
$responseNode->appendChild(
$this->_xml->createElement('return')
);
}

$this->_xml->appendChild($responseNode);
return $this->_xml->saveXML();
}
/**
* Modify the HTTP response object
* Remove the HTML body, replace with XML and change the content-type
*
* @param mixed $return
* @param Exception $exception
*/
private function _setResponse($return = false,Exception $exception = null)
{
$this->getResponse()->setHeader('Content-Type','text/xml; charset=UTF-8');
$this->getResponse()->clearBody();
$this->getResponse()->setBody(
$this->_getXML($return,$exception)
);
}
/**
* Serialize a mixed value to XML in DOMElement format
* This method can be used recursively in case of objects and arrays
*
* @param string $name
* @param mixed $value
* @return DOMElement
*/
private function _serialize($name,$value)
{
if(is_array($value)){
$element = $this->_xml->createElement($name);
foreach ($value as $k=>$v){
if(is_numeric($k)){
$k = 'item';
}
$element->appendChild($this->_serialize($k,$v));
}
} elseif(is_object($value)){
$element = $this->_xml->createElement($name);
$reflection = new ReflectionObject($value);
$properties = $reflection->getProperties();
foreach ($properties as $property){
if($property->isPublic()){
$element->appendChild(
$this->_serialize(
$property->getName(),
$property->getValue($value)
)
);
}
}
}else{
$element = $this->_xml->createElement(
$name,
(string)$value
);
}
return $element;
}
/**
* preDispatch hook that retrieves if an Exception was thrown in the application
* If an exception is thrown, the exception is passed to the exception part of the XML output and script execution is terminated
*
* @param Zend_Controller_Request_Abstract $request
*/
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
if($this->getResponse()->isException()){
$exArray = $this->getResponse()->getException();
$this->_setResponse(null,$exArray[0]);
$this->getResponse()->sendResponse();
exit();
}
}
/**
* postDispatch hook that serializes the view object to XML by modifying the HTTP response
* If no exception was thrown script execution continues and the postDispatch method will be called
*
* @param Zend_Controller_Request_Abstract $request
*/
public function postDispatch(Zend_Controller_Request_Abstract $request)
{
$view = Zend_Controller_Action_HelperBroker::getExistingHelper('ViewRenderer')->view;
$this->_setResponse($view);
}
}

The plugin registration

To activate the plugin, just call the registerPlugin method from the front controller. In my case this is done in my Initializer class which is allready a plugin.

$this->_front->registerPlugin(new My_Plugin_Xml());

The app

This application has one single controller which is the IndexController. There are 2 actions:

* IndexAction: the default action which assigns an object to the view
* ExceptionAction: an action which throws an exception

Pretty simple, pretty basic, but mind the exception: my plugin can catch it by hooking into the flow at preDispatch time. At that time we can already determine if the response contains an exception. Luckily, in this stage the front controller hasn’t yet sent additional error output to the view.

<?php
class IndexController extends Zend_Controller_Action
{
public function indexAction()
{
$obj = new stdClass();
$obj2 = new stdClass();
$obj2->c = 'xyz';
$obj2->d = '123';
$obj->a = 'abc';
$obj->b = $obj2;
$this->view->content= $obj;
}
public function exceptionAction()
{
throw new Exception('It all goes wrong!');
}
}

The output

indexAction

<?xml version="1.0" encoding="UTF-8"?>
<response>
<exception/>
<return>
<content>
<a>abc</a>
<b>
<c>xyz</c>
<d>123</d>
</b>
</content>
</return>
</response>

exceptionAction

<?xml version="1.0" encoding="UTF-8"?>
<response>
<exception>
<message>It all goes wrong!</message>
<code>0</code>
<type>Exception</type>
</exception>
<return/>
</response>