<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mihai Corlan &#187; PHP</title>
	<atom:link href="http://corlan.org/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://corlan.org</link>
	<description>Web, Mobile, and Rock&#38;Roll</description>
	<lastBuildDate>Mon, 30 Jan 2012 11:01:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Steps to deploy a Flex and PHP application</title>
		<link>http://corlan.org/2011/12/09/steps-to-deploy-a-flex-and-php-application/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=steps-to-deploy-a-flex-and-php-application</link>
		<comments>http://corlan.org/2011/12/09/steps-to-deploy-a-flex-and-php-application/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 07:57:02 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=3281</guid>
		<description><![CDATA[
			
				
			
		
I&#8217;ve been receiving a number of emails on this topic lately. It seems there is little information out there about how to move from development to production with a Flex and PHP application. Here is a simple checklist that could help you, especially if you are doing this for the first time. Please note that [...]]]></description>
			<content:encoded><![CDATA[<div class="none" style="float: right; margin-left: 10px;"><g:plusone href="http://corlan.org/2011/12/09/steps-to-deploy-a-flex-and-php-application/" size="tall" count="true"></g:plusone></div><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcorlan.org%2F2011%2F12%2F09%2Fsteps-to-deploy-a-flex-and-php-application%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2011%2F12%2F09%2Fsteps-to-deploy-a-flex-and-php-application%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;ve been receiving a number of emails on this topic lately. It seems there is little information out there about how to move from development to production with a Flex and PHP application. Here is a simple checklist that could help you, especially if you are doing this for the first time. Please note that I presume you used the Data Services (wizards) to connect the Flex client to PHP services.</p>
<ol>
<li>Make sure you have Zend Framework on your server. If you don&#8217;t, install it</li>
<li>Make sure you change MySQL credentials and server IP/name used by your PHP scripts to connect to the database</li>
<li>Copy the PHP services folder to your server. Then test these services. If they don&#8217;t work check the MySQL credentials or look for dependencies (maybe your PHP services use other PHP classes that you forgot to copy to your server)</li>
<li>Edit the amy_config.ini file and make sure the path to the Zend Framework is OK and set production to true</li>
<li>Edit the Flex services to point to your live server gateway.php. In the services folder of your Flex project you will find _Super_something.as files. In the constructor you will find a line like this:
<p><em> _serviceControl.endpoint = &#8220;http://localhost:10088/MobileFlexPHP-PHP/public/gateway.php&#8221;;</em><br /> Copy that line and then open the class that extends this _Super class and paste the line in the constructor. Then change the URL to reflect your server setup</li>
<li>Copy the bin-release/ folder to your server (you should choose the export release for your project; this will create a SWF file smaller than the debug version)</li>
</ol>
<p>That&#8217;s it! If I missed something please drop a comment!</p>
]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2011/12/09/steps-to-deploy-a-flex-and-php-application/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Slides from today&#8217;s webinar: Introduction to Flash Builder for PHP</title>
		<link>http://corlan.org/2011/05/18/slides-from-todays-webinar-introduction-to-flash-builder-for-php/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=slides-from-todays-webinar-introduction-to-flash-builder-for-php</link>
		<comments>http://corlan.org/2011/05/18/slides-from-todays-webinar-introduction-to-flash-builder-for-php/#comments</comments>
		<pubDate>Wed, 18 May 2011 15:42:47 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2872</guid>
		<description><![CDATA[
			
				
			
		
As I promised here are the slides Kevin and I used for today&#8217;s webinar:
Introduction to Flash Builder for PHP
Here is what we covered:

Short introduction to this new product &#8211; Flash Builder for PHP
Using the new Flex and PHP project wizard and discussing the generated projects
&#8220;Consuming&#8221; a PHP service from Flex
Building a simple UI to display [...]]]></description>
			<content:encoded><![CDATA[<div class="none" style="float: right; margin-left: 10px;"><g:plusone href="http://corlan.org/2011/05/18/slides-from-todays-webinar-introduction-to-flash-builder-for-php/" size="tall" count="true"></g:plusone></div><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcorlan.org%2F2011%2F05%2F18%2Fslides-from-todays-webinar-introduction-to-flash-builder-for-php%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2011%2F05%2F18%2Fslides-from-todays-webinar-introduction-to-flash-builder-for-php%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>As I promised here are the slides Kevin and I used for today&#8217;s webinar:</p>
<div id="__ss_8013132" style="width: 425px;"><strong style="display: block; margin: 12px 0 4px;"><a title="Introduction to Flash Builder for PHP" href="http://www.slideshare.net/mcorlan/introduction-flash-builder-for-php">Introduction to Flash Builder for PHP</a></strong><object id="__sse8013132" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=introduction-to-flash-builder-for-php-110518103456-phpapp01&amp;stripped_title=introduction-flash-builder-for-php&amp;userName=mcorlan" /><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=introduction-to-flash-builder-for-php-110518103456-phpapp01&amp;stripped_title=introduction-flash-builder-for-php&amp;userName=mcorlan" name="__sse8013132" allowscriptaccess="always" allowfullscreen="true"></embed></object></div>
<p>Here is what we covered:</p>
<ul>
<li>Short introduction to this new product &#8211; Flash Builder for PHP</li>
<li>Using the new Flex and PHP project wizard and discussing the generated projects</li>
<li>&#8220;Consuming&#8221; a PHP service from Flex</li>
<li>Building a simple UI to display data stored in the database</li>
<li>Explaining how the PHP remoting end point is configured (gateway.php)</li>
<li>Tips and tricks on using PHP doc to help Flash Builder generate the correct data type for return variables, arguments, and value objects.</li>
</ul>
<p>You can find the recording of the webinar <a href="http://eseminars.adobeconnect.com/p64272957/" target="_blank">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2011/05/18/slides-from-todays-webinar-introduction-to-flash-builder-for-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating Flex Mobile Apps with Flash Builder for PHP</title>
		<link>http://corlan.org/2011/05/05/creating-flex-mobile-apps-with-flash-builder-for-php/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=creating-flex-mobile-apps-with-flash-builder-for-php</link>
		<comments>http://corlan.org/2011/05/05/creating-flex-mobile-apps-with-flash-builder-for-php/#comments</comments>
		<pubDate>Thu, 05 May 2011 16:18:37 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2840</guid>
		<description><![CDATA[
			
				
			
		
As you might have heard, we released earlier this week Flash Builder and Flex 4.5. Part of this release is a new product called Flash Builder for PHP 4.5. This is something you should make sure you try if you are a PHP and Flash/Flex developer.
So what is Flash Builder for PHP? This product will [...]]]></description>
			<content:encoded><![CDATA[<div class="none" style="float: right; margin-left: 10px;"><g:plusone href="http://corlan.org/2011/05/05/creating-flex-mobile-apps-with-flash-builder-for-php/" size="tall" count="true"></g:plusone></div><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcorlan.org%2F2011%2F05%2F05%2Fcreating-flex-mobile-apps-with-flash-builder-for-php%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2011%2F05%2F05%2Fcreating-flex-mobile-apps-with-flash-builder-for-php%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>As you might have heard, we released earlier this week Flash Builder and Flex 4.5. Part of this release is a new product called Flash Builder for PHP 4.5. This is something you should make sure you try if you are a PHP and Flash/Flex developer.</p>
<p>So what is Flash Builder for PHP? This product will install Flash Builder 4.5 with Zend Studio 8.1 as a plugin plus some additional plugins that integrate these two products. Using this IDE you can create mixed projects (Flex and PHP both for desktop and mobile devices) and you can streamline testing, deploying, debugging, and consuming PHP services via Flex remoting (with the help of Zend Framework).</p>
<p>Instead of writing a pretty long article, I decide to shoot a video tutorial on how you can create a Flex mobile app that uses a PHP service. This tutorial will walk you through:</p>
<ul>
<li>Using the new project type Flex Mobile and PHP</li>
<li>Creating a mobile application that has two views/screens. I will explain how to use the ViewNavigator and View classes to control your application state</li>
<li>Consuming a PHP service from a Flex mobile app using remoting</li>
<li>Testing and debugging the code (Flex and PHP) on the desktop simulator and physical device</li>
</ul>
<p>I hope you will enjoy this. If you want to download the files used for this tutorial, click <a href="http://corlan.org/downloads/flex-php-mobile.zip" target="_blank">here</a> (unzip the file and you will get the Flex project you can import it and the PHP files plus the database dump).</p>
<p><object width="400" height="220"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=23318739&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" /><embed type="application/x-shockwave-flash" width="400" height="220" src="http://vimeo.com/moogaloop.swf?clip_id=23318739&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=00adef&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" allowfullscreen="true" allowscriptaccess="always"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2011/05/05/creating-flex-mobile-apps-with-flash-builder-for-php/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>Working with Doctrine 2, Flex, Zend AMF, and Flash Builder</title>
		<link>http://corlan.org/2010/08/05/working-with-doctrine-2-flex-zend-amf-and-flash-builder/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=working-with-doctrine-2-flex-zend-amf-and-flash-builder</link>
		<comments>http://corlan.org/2010/08/05/working-with-doctrine-2-flex-zend-amf-and-flash-builder/#comments</comments>
		<pubDate>Thu, 05 Aug 2010 13:17:30 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://corlan.org/2010/08/05/working-with-doctrine-2-flex-zend-amf-and-flash-builder/</guid>
		<description><![CDATA[
			
				
			
		
I finally got some time to play with Doctrine 2 and Flex. Back in May I wrote an article about working with Doctrine 1.x and Flex (you can read the article here) and my feelings were mixed. I chatted with Jonathan Wage of Doctrine about some of the shortcomings I found in Doctrine 1.x and [...]]]></description>
			<content:encoded><![CDATA[<div class="none" style="float: right; margin-left: 10px;"><g:plusone href="http://corlan.org/2010/08/05/working-with-doctrine-2-flex-zend-amf-and-flash-builder/" size="tall" count="true"></g:plusone></div><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcorlan.org%2F2010%2F08%2F05%2Fworking-with-doctrine-2-flex-zend-amf-and-flash-builder%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F08%2F05%2Fworking-with-doctrine-2-flex-zend-amf-and-flash-builder%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I finally got some time to play with Doctrine 2 and Flex. Back in May I wrote an <a href="http://corlan.org/2010/05/05/working-with-doctrine-zend-framework-and-flex/" target="_blank">article</a> about working with Doctrine 1.x and Flex (you can read the article here) and my feelings were mixed. I chatted with Jonathan Wage of Doctrine about some of the shortcomings I found in Doctrine 1.x and his response was to check Doctrine 2 (still in development at the time of writing this article). Doctrine 2 is a big step forward.</p>
<p>In this article I describe how I rewrote the original application I created for my first article, this time using Doctrine 2, Flex 4, Zend Framework, and the Flash Builder data-centric development wizards. I’ll highlight the relevant differences between Doctrine 1 and Doctrine 2 along the way. Thus, you should find this article valuable in any one of these two cases:</p>
<ul>
<li>You are already working with Doctrine 1 and you&#8217;ve wondered what it would take to move to version 2</li>
<li>You want to learn how to use Doctrine 2 with Flex; you know PHP and you know enough Flex not to be scared away if you see some snippets of code</li>
</ul>
<p>Before going into the details let me say this: if you aren’t already using an ORM framework for PHP then you should. For most projects it can help you by freeing you of the tedious tasks of writing CRUD code and SQL queries. It allows you to focus on the business logic of your application. And all these advantages are multiplied when working on Rich Internet Applications because on this kind of project much of the work is done on the client and not on the server.</p>
<p>There are some aspects of using this ORM with RIA that could be better, but hey we don’t live in a perfect world. Most of these things, I think, are related to the fact that every time you use a server side ORM with a rich client, you leave behind the main story used for creating that framework – you use the ORM in order to feed a rich client with data and enable the client to persist the changes. Thus you need additional boiler plate code to make the whole thing work.</p>
<p>If you don’t know much about ORMs in general, you may want to read my first <a href="http://corlan.org/2010/05/05/working-with-doctrine-zend-framework-and-flex/" target="_blank">article</a> first and before continuing.</p>
<p><span id="more-2115"></span></p>
<h2>The Big Picture</h2>
<p>Here is a screenshot of the application I built running in the browser:</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/08/figure1.jpg"><img style="display: inline; border-width: 0px;" title="figure-1" src="http://corlan.org/wp-content/uploads/2010/08/figure1_thumb.jpg" border="0" alt="figure-1" width="600" height="338" /></a></p>
<p>below is the database structure. The only difference between this database and the one used in the previous article is the addition of a simple primary key to the <em>marks </em>table.</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/08/figure2.jpg"><img style="display: inline; border-width: 0px;" title="figure-2" src="http://corlan.org/wp-content/uploads/2010/08/figure2_thumb.jpg" border="0" alt="figure-2" width="300" height="252" /></a></p>
<p>While this is by no means a complex application, I think it’s a decent one in terms of relations between tables: I have a number of courses and countries (courses and countries tables), and each student belongs to a country (many-to-one between students and countries) and receives marks for a number of courses (marks many-to-many table for students and courses tables).</p>
<p>The Flex application reads all the data stored in the MySQL database and lets the user fully edit students by performing the following operations:</p>
<ul>
<li>Add, edit, delete students</li>
<li>Change the country for a student</li>
<li>Change the courses taken by a student and assign marks for a course</li>
</ul>
<p>And here is an overview of the different parties involved in this application:</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/08/figure6.png"><img style="display: inline; border-width: 0px;" title="figure-6" src="http://corlan.org/wp-content/uploads/2010/08/figure6_thumb.png" border="0" alt="figure-6" width="600" height="220" /></a></p>
<h2>Differences between Doctrine 2 and 1.x</h2>
<p>Before explaining how I built the app, let’s talk a little bit about the main differences between Doctrine 2 and Doctrine 1.x (as I’m writing this article Doctrine 2 is still in Beta, so things could change).</p>
<p>The biggest change by far is the one related to the main pattern used by the Doctrine 2 ORM. In 1.x versions it used the Active Record pattern (Ruby on Rails uses Active Record too), now you can say goodbye to Active Record and welcome Data Mapper (Hibernate uses the same pattern). What are the differences between these two patterns?</p>
<p>With Active Record the entities know how to persist themselves to the database; basically each entity extends some sort of a class from the ORM framework and implements methods like <em>read()</em>, <em>find()</em>, <em>delete()</em>, and <em>update()</em>. Although it is not mandatory, the entities look very much like the database structure.</p>
<p>With Data Mapper entities know nothing about the persistency layer and nothing about the database structure. The ORM provides the means to persist the entities and read the data into entities (from the database).</p>
<p>From a Rich Client perspective this translates in less work on the PHP side when preparing data for sending across the wire while using Doctrine 2. With Doctrine 1, the data model was heavy due to the Active Record pattern. Thus I had to create a plain vanilla data model used to send the data to the Flex client. In order to efficiently transform the heavy entities used by Doctrine 1 into the plain vanilla ones used for sending the data to Flex, I had to write custom functions. When data came in from the Flex client, the reverse process was needed: use the plain vanilla objects to build the Doctrine entity objects. An alternative could be to send all the data to Flex as arrays. Unfortunately, this approach doesn’t work out of the box; you have to write functions to transform the graph of objects into a graph of arrays/associative arrays.</p>
<p>With Doctrine 2, I don’t need this extra layer of simple value objects and I can return the data as a graph of objects or arrays with the built-in capabilities.</p>
<p>The second big difference is that Doctrine 2 requires PHP 5.3 or newer. Thus, if your setup requires older versions of PHP, then you have to stick with Doctrine 1.x.</p>
<p>Of course the ripples stirred by these two changes are quite big and I think it is safe to say that when moving from Doctrine 1.x to 2 you won’t reuse much of your previous experience with Doctrine 1.x or the code you wrote.</p>
<p>Having said this, I have to say that I, for one, am happy with the evolution of Doctrine, because I favor Data Mapper over Active Record.</p>
<h2>Installing Doctrine 2 and creating the PHP project</h2>
<p>First of all you need to get the Doctrine framework. There are four different ways (PEAR , Package Download, GitHub, or SVN). Depending on what method you use the configuration of Doctrine will differ a little bit. I used GitHub for my project, and I pulled out the code outside of Apache’s web root.</p>
<p>Speaking of the project, I used Eclipse PDT with Flash Builder 4 (I installed the Flash Builder plug-in on top of Eclipse PDT). The first step after getting the Doctrine framework was creating a PHP project named <em>students-doctrine2</em>. Next I added Flex nature to the project by right-clicking on the project name and choosing <em>Add/Change Project Type…</em> &gt; <em>Add Flex project type</em> from the contextual menu. Make sure you select <em>PHP</em> for the <em>Application Server type</em> and you fill in the path and URL for your web root.</p>
<p>The next step was to create a folder inside the web root where I’ll put the PHP services, entities, and Doctrine’s configuration files: <em>doctrine2_students</em>. Inside of it, I created three folders named <em>entities</em>, <em>proxies</em>, and <em>services</em>. And finally, I created a linked resource between <em>doctrine2_students</em> folder and my Eclipse project (right-click on the project, choose <em>New</em> &gt; <em>Folder</em> and then click on <em>Advance</em> button and navigate to the folder location). With that I was ready to write PHP and Flex code.</p>
<p>The next step is to create a bootstrap file (I call it <em>bootstrap.php</em> and place it inside of the <em>doctrine2_students</em> folder) that configures Doctrine 2 to be usable with my project. This means to load the framework classes, set up database access information, specify entities location and annotation method, and configure the different caches that will be used by the app. In the same bootstrap file I created an instance of the <em>EntityManager</em> class. This is the entry point to the Doctrine 2. If you download the project source code (see the links from the second to last section) you’ll find the <em>bootstrap.php</em> file inside of the <em>doctrine2_students</em> folder. The file looks like this:</p>
<div style="border: 1px solid gray; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text;">
<div style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">&lt;?php</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">use Doctrine\ORM\EntityManager,</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    Doctrine\ORM\Configuration;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$applicationMode = <span style="color: #006080;">'development'</span>;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">//Doctrine Git bootstrap</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$lib = <span style="color: #006080;">'/Users/mcorlan/Documents/work/_git/doctrine/doctrine2/lib/'</span>;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">require $lib . <span style="color: #006080;">'vendor/doctrine-common/lib/Doctrine/Common/ClassLoader.php'</span>;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$classLoader = <span style="color: #0000ff;">new</span> \Doctrine\Common\ClassLoader(<span style="color: #006080;">'Doctrine\Common'</span>, $lib . <span style="color: #006080;">'vendor/doctrine-common/lib'</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$classLoader-&gt;register();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$classLoader = <span style="color: #0000ff;">new</span> \Doctrine\Common\ClassLoader(<span style="color: #006080;">'Doctrine\DBAL'</span>, $lib . <span style="color: #006080;">'vendor/doctrine-dbal/lib'</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$classLoader-&gt;register();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$classLoader = <span style="color: #0000ff;">new</span> \Doctrine\Common\ClassLoader(<span style="color: #006080;">'Doctrine\ORM'</span>, $lib);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$classLoader-&gt;register();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">//additional Symphony components for Doctrine-CLI Tool, YAML Mapping driver</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$classloader = <span style="color: #0000ff;">new</span> \Doctrine\Common\ClassLoader(<span style="color: #006080;">'Symfony'</span>, $lib . <span style="color: #006080;">'vendor/'</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$classloader-&gt;register();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">//load entities</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$classloader = <span style="color: #0000ff;">new</span> \Doctrine\Common\ClassLoader(<span style="color: #006080;">'entities'</span>, __DIR__);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$classloader-&gt;register();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$classLoader = <span style="color: #0000ff;">new</span> \Doctrine\Common\ClassLoader(<span style="color: #006080;">'proxies'</span>, __DIR__);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$classLoader-&gt;register();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">//load services</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$classLoader = <span style="color: #0000ff;">new</span> \Doctrine\Common\ClassLoader(<span style="color: #0000ff;">null</span>, __DIR__ . <span style="color: #006080;">'/services'</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$classLoader-&gt;register();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #0000ff;">if</span> ($applicationMode == <span style="color: #006080;">'development'</span>) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $cache = <span style="color: #0000ff;">new</span> \Doctrine\Common\Cache\ArrayCache;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">} <span style="color: #0000ff;">else</span> {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $cache = <span style="color: #0000ff;">new</span> \Doctrine\Common\Cache\XcacheCache();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">}</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$config = <span style="color: #0000ff;">new</span> Configuration;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$config-&gt;setMetadataCacheImpl($cache);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$driverImpl = $config-&gt;newDefaultAnnotationDriver(__DIR__ . <span style="color: #006080;">'/entities'</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$config-&gt;setMetadataDriverImpl($driverImpl);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$config-&gt;setQueryCacheImpl($cache);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$config-&gt;setProxyDir(dirname(__FILE__) .<span style="color: #006080;">'/proxies'</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$config-&gt;setProxyNamespace(<span style="color: #006080;">'doctrine2_students\proxies'</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #0000ff;">if</span> ($applicationMode == <span style="color: #006080;">"development"</span>) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $config-&gt;setAutoGenerateProxyClasses(<span style="color: #0000ff;">true</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">} <span style="color: #0000ff;">else</span> {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $config-&gt;setAutoGenerateProxyClasses(<span style="color: #0000ff;">false</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">}</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">//database connection config</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$connectionOptions = array(</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #006080;">'driver'</span> =&gt; <span style="color: #006080;">'pdo_mysql'</span>,</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #006080;">'dbname'</span> =&gt; <span style="color: #006080;">'students'</span>,</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #006080;">'user'</span> =&gt; <span style="color: #006080;">'mihai'</span>,</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #006080;">'password'</span> =&gt; <span style="color: #006080;">'mihai'</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$GLOBALS[<span style="color: #006080;">'em'</span>] = EntityManager::create($connectionOptions, $config);</pre>
</div>
</div>
<h2>Creating the PHP entities</h2>
<p>With Doctrine 2 (and any ORM that uses the Data Mapper pattern) you have to specify how an entity is persisted by the framework and what relationships it has with other entities (if any). in Doctrine 2 you can choose from four different methods: annotations, YAML, XML, and plain PHP. I initially favored the first one because all the information is stored in the entities classes as PHPDoc comments. Thus if you want to modify an entity you have only one place to look for it. However, after using this approach I think the XML approach is best because you get code-completion hints. Here is the listing for the <em>Course</em> entity (remember I have four tables in my database and I need four entities for my application):</p>
<div style="border: 1px solid gray; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text;">
<div style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">&lt;?php</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #0000ff;">namespace</span> entities;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">/** @Entity </span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;"> * @Table(name="courses") </span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;"> */</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #0000ff;">class</span> Course {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #008000;">/**</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">     * @Id @Column(type="integer")</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">     * @GeneratedValue(strategy="AUTO")</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">     */</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #0000ff;">private</span> $id;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #008000;">/** </span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">     * @Column(type="string", length=255) </span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">     */</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #0000ff;">private</span> $name;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getId() {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        <span style="color: #0000ff;">return</span> $<span style="color: #0000ff;">this</span>-&gt;id;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getName() {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        <span style="color: #0000ff;">return</span> $<span style="color: #0000ff;">this</span>-&gt;name;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> setName($val) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        $<span style="color: #0000ff;">this</span>-&gt;name = $val;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">}</pre>
</div>
</div>
<p>Using annotations you specify what table is used for the entity (remember one row from that table will be wrapped in one instance of the entity). You can set different names for the properties if you want (in SQL you don’t use camelCase notation, but in PHP or ActionScript typically you use this convention).</p>
<p>The entities I created closely follow the structure of the database. The only difference is in how the foreign keys are represented. For example, the <em>Student</em> entity, which has a many-to-one relation with the <em>Country</em> entity, doesn&#8217;t have a property <em>country_id</em> of type int. Instead, I added a property called <em>country</em> that is of <em>Country</em> type. Similarly, I created a property called <em>marks</em> that holds an array of <em>Mark</em> entities – if a student attends three courses, then its <em>marks</em> property will hold an array of <em>Mark</em> objects with three instances.</p>
<p>Here are some notes on creating entities with Doctrine 2:</p>
<ul>
<li>With Doctrine 1 I used the built-in tools to create the domain model from the database structure</li>
<li>Doctrine 2 has support to create the YAML out of the database schema, and then generate the entities; however I’m not sure it is good idea to do this. If you have complex schemas the generated code might not worked as you expect, and you’ll need to tweak it manually anyway</li>
<li>You have to remember to set the properties as private/protected and not public, and add getters/setters. If you fail to do this, you might get nasty bugs (Doctrine will have problems injecting the code to handle relations).</li>
</ul>
<h2>Creating the PHP services</h2>
<p>With the four entities in place, it is time to create the PHP services. These will be the services used by the Flex client to get and persist data. Basically, using the Zend Framework I’ll be able to invoke remote procedure calls on these objects from the Flex side.</p>
<p>Inside the <em>doctrine2_students/services/</em> folder I created four PHP files: <em>CountriesService.php</em>, <em>CoursesService.php</em>, <em>MarksService.php</em>, and <em>StudentsService.php</em>.  I edited the <em>bootstrap.php</em> file to load the <em>services</em> folder along with the rest of the files. Here is the listing for the <em>CountriesService</em> class:</p>
<div style="border: 1px solid gray; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text;">
<div style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">&lt;?php</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">require_once(__DIR__.<span style="color: #006080;">'/../bootstrap.php'</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #0000ff;">class</span> CountriesService {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __construct() {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        $<span style="color: #0000ff;">this</span>-&gt;entityManager = $GLOBALS[<span style="color: #006080;">'em'</span>];</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getCountries() {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        $q = $<span style="color: #0000ff;">this</span>-&gt;entityManager-&gt;createQuery(<span style="color: #006080;">'SELECT c FROM entities\Country c ORDER BY c.name'</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        <span style="color: #0000ff;">return</span> $q-&gt;getArrayResult();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">}</pre>
</div>
</div>
<p>As you might expect, the complex code is inside of <em>StudentsService</em> class; here’s the public API:</p>
<div style="border: 1px solid gray; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text;">
<div style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #0000ff;">class</span> StudentsService {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #008000;">//returns all the students</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getStudents() {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        ...</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #008000;">//save changes for an existent student, or insert a new one</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> saveStudent($student) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        ...</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #008000;">//deletes a student</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> deleteStudent($student) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        ...</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">}</pre>
</div>
</div>
<p>As I said before, the entry point to Doctrine 2 is its <em>EntityManager</em> class. You can use this class to query for persistent objects using different methods. The most powerful method is Doctrine Query Language (DQL) which resembles SQL but works on the entities you’ve defined in your domain model rather than on the underlying tables.</p>
<p>If, for example, you want to retrieve the country with the id equal to 1, you could use this code:</p>
<div style="border: 1px solid gray; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text;">
<div style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$id = 1;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$dql = <span style="color: #006080;">'SELECT c FROM entities\Country c WHERE id = ?1'</span>;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$query = $entityManager-&gt;createQuery($dql);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$query-&gt;setParameter(1, $id);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$countryEntity = $query-&gt;getResult();</pre>
</div>
</div>
<p>If you want to change the name for this country, you’d write this code:</p>
<div style="border: 1px solid gray; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text;">
<div style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$countryEntity-&gt;setName(<span style="color: #006080;">'new name for your country'</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">//persist the changes to database</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$entityManager-&gt;flush();</pre>
</div>
</div>
<p>If you want to create a new country, you’d write this code:</p>
<div style="border: 1px solid gray; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text;">
<div style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$countryEntity = <span style="color: #0000ff;">new</span> entities\Country();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$countryEntity-&gt;setName(<span style="color: #006080;">'Mihai\'s country'</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">//set the entity to be managed by Doctrine</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$entityManager-&gt;persist($countryEntity);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">//persist the changes to database</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$entityManager-&gt;flush();</pre>
</div>
</div>
<p>Whith DQL when you write a join, it can be a filtering join (similar to the concept of join in SQL used for limiting or aggregating results) or a fetch join (used to fetch related records and include them in the result of the main query). When you include fields from the joined entity in the <em>SELECT</em> clause you get a fetch join. Here is the code for the <em>StudentsService-&gt;getStudents()</em> method:</p>
<div style="border: 1px solid gray; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text;">
<div style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$dql = <span style="color: #006080;">"SELECT s, c, m, e FROM entities\Student s </span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            JOIN s.country c JOIN s.marks m</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            JOIN m.course e ORDER BY s.lastName, s.firstName";</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$q = $<span style="color: #0000ff;">this</span>-&gt;entityManager-&gt;createQuery($dql);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #0000ff;">return</span> $q-&gt;getArrayResult();</pre>
</div>
</div>
<p>Each student is retrieved along with the country he belongs to and all of his courses from the many-to-many table &#8211; all with a single DQL query. And if you <em>print_r()</em> the result you’ll see a structure along these lines:</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/08/figure3.jpg"><img style="display: inline; border-width: 0px;" title="figure-3" src="http://corlan.org/wp-content/uploads/2010/08/figure3_thumb.jpg" border="0" alt="figure-3" width="469" height="1066" /></a></p>
<p>In addition, when you create these kinds of queries with fetch joins and you use <em>getArrayResult()</em> method on the query object instead of <em>getResult()</em>, you get a nice array or associative array of other arrays. These data are ready to be sent to the Flex client without any transformation.</p>
<p>The only part I haven’t discussed is how I handle the changes for a <em>Student</em>. I will talk about this as part of the Flex client.</p>
<p>For the communication between the Flex and PHP side I’ll use remoting. On the PHP side I need Zend AMF in order to enable remoting. But for the purposes of this article I will let Flash Builder 4 handle this (installing Zend Framework and creating the gateway for exposing the four PHP services I created).</p>
<h2>Creating the Flex client</h2>
<p>With the server code in place, it is time to add the Flex code. In the previous article I wrote all client code manually. This time I’ll use the data-centric development features of Flash Builder to introspect PHP classes and create the service wrappers as well as the ActionScript value objects.</p>
<p>The easiest way to do this, is to first create the four services, and then to define the return types for the <em>getStuff()</em> operations. Follow these steps:</p>
<ol>
<li>From the <em>Data/Services</em> view click the <em>Connect to Data/Service</em> link for the first service or on the third icon (the one with a + sign) for the other three services</li>
<li>When the wizard opens, select PHP, and click <em>Next</em>. If it is your first time using the wizard for PHP, then you’ll be presented with a dialogue to install the Zend Framework</li>
<li>Click <em>Browse</em> and select the first PHP service</li>
<li>Repeat these three steps until you have defined all the four services. Please note that you can change the packages where the services and the value objects will be created</li>
</ol>
<p><a href="http://corlan.org/wp-content/uploads/2010/08/figure4.jpg"><img style="display: inline; border-width: 0px;" title="figure-4" src="http://corlan.org/wp-content/uploads/2010/08/figure4_thumb.jpg" border="0" alt="figure-4" width="574" height="203" /></a></p>
<p>Now, it is time to define the value objects I’ll use on the Flex side. Again I’ll use the data-centric development features:</p>
<ol>
<li>Because the <em>StudentsService</em> returns a complex type that uses <em>Student</em>, <em>Course</em>, <em>Country,</em> and <em>Mark</em> it is important to start defining the return types first with <em>CountriesService</em> and <em>CoursesService</em>, then for <em>MarksService</em>, and finally for <em>StudentsService</em></li>
<li>To define the return type for an operation on as service, expand the tree for the service, and right-click the operation (for example, select <em>getCountries()</em> from <em>CountriesService</em>) and choose <em>Configure Return Type </em>from the context menu. When the wizard opens, make sure the first option is selected on the first screen (<em>Auto-detect the return type from the sample data</em>) and click <em>Next</em></li>
<li>On the second page you can enter a name for the value object class (for example <em>Country</em>)</li>
<li>The most complex type is the return type for the <em>StudentsService.getStudents()</em> method. For this one, on the second page of the wizard you need to expand the nodes and choose for the type column, the types you defined earlier (<em>Course</em>, <em>Country</em>, or <em>Mark</em>)</li>
</ol>
<p>Here is how the <em>Student</em> value object is presented in the <em>Data/Services</em> view after finishing the above steps:</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/08/figure5.jpg"><img style="display: inline; border-width: 0px;" title="figure-5" src="http://corlan.org/wp-content/uploads/2010/08/figure5_thumb.jpg" border="0" alt="figure-5" width="288" height="256" /></a></p>
<p>With the service wrappers and value objects in place, it is time to take care of the application UI and put these files to use. For this task I reuse most of the code I wrote in my previous application. I had to tweak some of the methods a little (for example, <em>saveStudent()</em> and <em>onStudentSelection()</em>).</p>
<p>When the application starts, the first thing I want it to do is load the <em>courses</em>, <em>countries</em>, and <em>students</em>. To do so, I created an <em>init()</em> function and registered it on the <em>creationComplete</em> event of the application. Then, I selected the <em>getStudents()</em> method from the <em>Data/Services</em> view, right-clicked it, and chose <em>Generate Service Call</em>. This command adds to the code an instance of <em>StudentsService</em>, an instance of CallResponder (you use this object to retrieve the result using the <em>lastResult</em> property or to register a <em>result</em>/<em>fault</em> listener for that operation), and a method that makes the call to the selected operation and assigns the <em>token</em> returned by the operation to the <em>token</em> property of the <em>CallResponder</em> object:</p>
<div style="border: 1px solid gray; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text;">
<div style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> getStudents():<span style="color: #0000ff;">void</span> {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    getStudentsResult.token = studentsService.getStudents();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">}</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">…</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">&lt;s:CallResponder id=<span style="color: #006080;">"getStudentsResult"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">&lt;services:StudentsService id=<span style="color: #006080;">"studentsService"</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">fault=<span style="color: #006080;">"Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)"</span> showBusyCursor=<span style="color: #006080;">"true"</span>/&gt;</pre>
</div>
</div>
<p>Another change from the first article is the use of bidirectional binding for the <em>firstName</em>, <em>lastName</em>, and <em>registration</em> fields of the form.</p>
<p>Here is the complete code of the Main.mxml where the magic happens:</p>
<div style="border: 1px solid gray; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; height: 256px; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text;">
<div style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">&lt;?xml version=<span style="color: #006080;">"1.0"</span> encoding=<span style="color: #006080;">"utf-8"</span>?&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">&lt;s:Application xmlns:fx=<span style="color: #006080;">"http://ns.adobe.com/mxml/2009"</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">               xmlns:s=<span style="color: #006080;">"library://ns.adobe.com/flex/spark"</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">               xmlns:mx=<span style="color: #006080;">"library://ns.adobe.com/flex/mx"</span> minWidth=<span style="color: #006080;">"955"</span> minHeight=<span style="color: #006080;">"600"</span> xmlns:services=<span style="color: #006080;">"org.corlan.services.*"</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">               creationComplete=<span style="color: #006080;">"init()"</span> xmlns:entities=<span style="color: #006080;">"org.corlan.entities.*"</span>&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    &lt;fx:Declarations&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;s:CallResponder id=<span style="color: #006080;">"getStudentsResult"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;services:StudentsService id=<span style="color: #006080;">"studentsService"</span> fault=<span style="color: #006080;">"Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)"</span> showBusyCursor=<span style="color: #006080;">"true"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;s:CallResponder id=<span style="color: #006080;">"getCountriesResult"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;services:CountriesService id=<span style="color: #006080;">"countriesService"</span> fault=<span style="color: #006080;">"Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)"</span> showBusyCursor=<span style="color: #006080;">"true"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;s:CallResponder id=<span style="color: #006080;">"getCoursesResult"</span> result=<span style="color: #006080;">"onCourses()"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;services:CoursesService id=<span style="color: #006080;">"coursesService"</span> fault=<span style="color: #006080;">"Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)"</span> showBusyCursor=<span style="color: #006080;">"true"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;entities:Student id=<span style="color: #006080;">"student"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;s:CallResponder id=<span style="color: #006080;">"deleteStudentResult"</span> result=<span style="color: #006080;">"getStudents()"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;s:CallResponder id=<span style="color: #006080;">"saveStudentResult"</span> result=<span style="color: #006080;">"getStudents()"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    &lt;/fx:Declarations&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    &lt;fx:Script&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;![CDATA[</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            import mx.collections.ArrayCollection;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            import mx.controls.Alert;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            import mx.events.FlexEvent;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            import mx.events.ListEvent;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            import org.corlan.entities.Country;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            import org.corlan.entities.Course;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            import org.corlan.entities.Mark;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            import org.corlan.entities.Student;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">var</span> marks:Array;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> onCourses():<span style="color: #0000ff;">void</span> {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                marks = <span style="color: #0000ff;">new</span> Array();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                <span style="color: #0000ff;">var</span> c:Array = (getCoursesResult.lastResult <span style="color: #0000ff;">as</span> ArrayCollection).toArray();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i:<span style="color: #0000ff;">int</span>=0; i&lt;c.length; i++) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    marks.push(</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                            {id : 0, mark : 0, course : c[i]}</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                        );</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                dgMarks.dataProvider = marks;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> customLabel(data:Object, column:DataGridColumn):String {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                <span style="color: #0000ff;">var</span> arr:Array = <span style="color: #0000ff;">new</span> Array();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                <span style="color: #0000ff;">var</span> c:<span style="color: #0000ff;">int</span> = (data <span style="color: #0000ff;">as</span> Student).marks.length;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                <span style="color: #0000ff;">var</span> mark:Mark;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i:<span style="color: #0000ff;">int</span> = 0; i&lt;c; i++) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    mark = (data <span style="color: #0000ff;">as</span> Student).marks[i] <span style="color: #0000ff;">as</span> Mark;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    arr.push(mark.course.name);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                <span style="color: #0000ff;">if</span> (arr.length &gt; 0)</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    <span style="color: #0000ff;">return</span> arr.join(<span style="color: #006080;">", "</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                <span style="color: #0000ff;">return</span> <span style="color: #006080;">"NONE"</span>;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> init():<span style="color: #0000ff;">void</span> {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                getCountries();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                getCourses();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                getStudents();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> getStudents():<span style="color: #0000ff;">void</span> {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                getStudentsResult.token = studentsService.getStudents();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> getCountries():<span style="color: #0000ff;">void</span>     {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                getCountriesResult.token = countriesService.getCountries();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> getCourses():<span style="color: #0000ff;">void</span> {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                getCoursesResult.token = coursesService.getCourses();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> saveStudent():<span style="color: #0000ff;">void</span> {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                <span style="color: #0000ff;">var</span> m:Mark;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                student.marks = <span style="color: #0000ff;">new</span> ArrayCollection();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i:<span style="color: #0000ff;">int</span> = 0, l:<span style="color: #0000ff;">int</span> = marks.length; i&lt;l; i++) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    <span style="color: #0000ff;">if</span> (marks[i][<span style="color: #006080;">"mark"</span>] &gt; 0) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                        m = <span style="color: #0000ff;">new</span> Mark();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                        m.course = marks[i][<span style="color: #006080;">"course"</span>];</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                        m.mark = marks[i][<span style="color: #006080;">"mark"</span>];</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                        student.marks.addItem(m);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                student.country = country.selectedItem <span style="color: #0000ff;">as</span> Country;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                saveStudentResult.token = studentsService.saveStudent(student);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> onStudentSelection(e:ListEvent):<span style="color: #0000ff;">void</span> {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                student = e.itemRenderer.data <span style="color: #0000ff;">as</span> Student;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                <span style="color: #0000ff;">if</span> (student.country) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    <span style="color: #0000ff;">var</span> l:<span style="color: #0000ff;">int</span> = getCountriesResult.lastResult.length;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i:<span style="color: #0000ff;">int</span> = 0; i&lt;l; i++) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                        <span style="color: #0000ff;">if</span> (getCountriesResult.lastResult[i].id == student.country.id) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                            country.selectedIndex = i;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                            <span style="color: #0000ff;">break</span>;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                        }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                <span style="color: #0000ff;">if</span> (student.marks &amp;&amp; student.marks.length &gt; 0) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    <span style="color: #0000ff;">var</span> k:<span style="color: #0000ff;">int</span> = marks.length;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    <span style="color: #0000ff;">var</span> o:Object;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> j:<span style="color: #0000ff;">int</span> = 0; j&lt;k; j++) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                        o = marks[j];</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                        o[<span style="color: #006080;">"mark"</span>] = 0;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                        <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> jj:<span style="color: #0000ff;">int</span> = 0; jj &lt; student.marks.length; jj++) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                            <span style="color: #0000ff;">if</span> ((student.marks[jj] <span style="color: #0000ff;">as</span> Mark).course.id == (o[<span style="color: #006080;">"course"</span>] <span style="color: #0000ff;">as</span> Course).id) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                                o[<span style="color: #006080;">"mark"</span>] = student.marks[jj].mark;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                                <span style="color: #0000ff;">break</span>;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                            }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                        }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    dgMarks.dataProvider = marks;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> deleteStudent():<span style="color: #0000ff;">void</span> {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                <span style="color: #0000ff;">if</span> (!student || !student.id)</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    <span style="color: #0000ff;">return</span>;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                deleteStudentResult.token = studentsService.deleteStudent(student);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        ]]&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    &lt;/fx:Script&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    &lt;mx:DataGrid id=<span style="color: #006080;">"dgStudents"</span> x=<span style="color: #006080;">"13"</span> y=<span style="color: #006080;">"14"</span> dataProvider=<span style="color: #006080;">"{getStudentsResult.lastResult}"</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                 itemClick=<span style="color: #006080;">"onStudentSelection(event)"</span>&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;mx:columns&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            &lt;mx:DataGridColumn headerText=<span style="color: #006080;">"First"</span> dataField=<span style="color: #006080;">"firstName"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            &lt;mx:DataGridColumn headerText=<span style="color: #006080;">"Last"</span> dataField=<span style="color: #006080;">"lastName"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            &lt;mx:DataGridColumn headerText=<span style="color: #006080;">"Country"</span> dataField=<span style="color: #006080;">"country.name"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            &lt;mx:DataGridColumn headerText=<span style="color: #006080;">"Courses"</span> labelFunction=<span style="color: #006080;">"customLabel"</span> width=<span style="color: #006080;">"200"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;/mx:columns&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    &lt;/mx:DataGrid&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    &lt;s:Button click=<span style="color: #006080;">"getStudents()"</span> label=<span style="color: #006080;">"Get Students"</span> x=<span style="color: #006080;">"13"</span> y=<span style="color: #006080;">"200"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    &lt;s:Button x=<span style="color: #006080;">"112"</span> y=<span style="color: #006080;">"200"</span> label=<span style="color: #006080;">"New"</span> click=<span style="color: #006080;">"student = new Student();"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    &lt;s:Button x=<span style="color: #006080;">"190"</span> y=<span style="color: #006080;">"200"</span> label=<span style="color: #006080;">"Delete Selected Student"</span> click=<span style="color: #006080;">"deleteStudent()"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    &lt;mx:Form x=<span style="color: #006080;">"510"</span> y=<span style="color: #006080;">"0"</span>&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;mx:FormItem label=<span style="color: #006080;">"First:"</span>&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            &lt;s:TextInput id=<span style="color: #006080;">"first"</span> text=<span style="color: #006080;">"@{student.firstName}"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;/mx:FormItem&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;mx:FormItem label=<span style="color: #006080;">"Last:"</span>&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            &lt;s:TextInput id=<span style="color: #006080;">"last"</span> text=<span style="color: #006080;">"@{student.lastName}"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;/mx:FormItem&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;mx:FormItem label=<span style="color: #006080;">"Registration:"</span>&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            &lt;mx:DateField id=<span style="color: #006080;">"registration"</span> selectedDate=<span style="color: #006080;">"@{student.registration}"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;/mx:FormItem&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;mx:FormItem label=<span style="color: #006080;">"Country:"</span>&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            &lt;s:List id=<span style="color: #006080;">"country"</span> dataProvider=<span style="color: #006080;">"{getCountriesResult.lastResult}"</span> labelField=<span style="color: #006080;">"name"</span> height=<span style="color: #006080;">"150"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;/mx:FormItem&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;mx:FormItem label=<span style="color: #006080;">"Marks:"</span>&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            &lt;mx:DataGrid id=<span style="color: #006080;">"dgMarks"</span> editable=<span style="color: #006080;">"true"</span>&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                &lt;mx:columns&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    &lt;mx:DataGridColumn headerText=<span style="color: #006080;">"Course"</span> dataField=<span style="color: #006080;">"course.name"</span> editable=<span style="color: #006080;">"false"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    &lt;mx:DataGridColumn headerText=<span style="color: #006080;">"Mark"</span> dataField=<span style="color: #006080;">"mark"</span> editable=<span style="color: #006080;">"true"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                &lt;/mx:columns&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            &lt;/mx:DataGrid&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;/mx:FormItem&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;mx:FormItem&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            &lt;s:Button label=<span style="color: #006080;">"Save"</span> click=<span style="color: #006080;">"saveStudent()"</span>/&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        &lt;/mx:FormItem&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    &lt;/mx:Form&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">&lt;/s:Application&gt;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
</div>
</div>
<p>Now, when I call the <em>saveStudent()</em> method I make a call to the remote operation (<em>saveStudent()</em> from the <em>StudentsService.php</em>) and pass along an instance of the <em>Student</em> ActionScript class. In the PHP method (<em>StudentsService-&gt;saveStudent()</em>) I get an anonymous Object, so I had to manually build an instance of the <em>Student</em> entity and populate it with the data. Here is the complete code for the server side <em>saveStudent()</em> method:</p>
<div style="border: 1px solid gray; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text;">
<div style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> saveStudent($student) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #0000ff;">if</span> ($student-&gt;id) { <span style="color: #008000;">//update</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        $entity = $<span style="color: #0000ff;">this</span>-&gt;entityManager-&gt;find(<span style="color: #006080;">'entities\Student'</span>, $student-&gt;id);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        <span style="color: #0000ff;">if</span> (!$entity)</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> Exception(<span style="color: #006080;">'Error saving student!'</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        $marks = $entity-&gt;getMarks();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        <span style="color: #0000ff;">foreach</span> ($marks <span style="color: #0000ff;">as</span> $mark) { <span style="color: #008000;">//update mark value for existent records</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            $found = <span style="color: #0000ff;">false</span>;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            <span style="color: #0000ff;">foreach</span> ($student-&gt;marks <span style="color: #0000ff;">as</span> $record) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                <span style="color: #0000ff;">if</span> ($mark-&gt;getCourse()-&gt;getId() == $record-&gt;course-&gt;id) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    $mark-&gt;setMark($record-&gt;mark);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    $found = <span style="color: #0000ff;">true</span>;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    $key = array_search($record, $student-&gt;marks, <span style="color: #0000ff;">true</span>); <span style="color: #008000;">//remove the $record from array</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    <span style="color: #0000ff;">if</span> ($key !== <span style="color: #0000ff;">false</span>)</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                        unset($student-&gt;marks[$key]);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                    <span style="color: #0000ff;">break</span>;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            <span style="color: #0000ff;">if</span> (!$found) { <span style="color: #008000;">//remove current mark</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                $entity-&gt;removeMark($mark);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">                $<span style="color: #0000ff;">this</span>-&gt;entityManager-&gt;remove($mark);<span style="color: #008000;">//remove mark from database</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">            }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    } <span style="color: #0000ff;">else</span> { <span style="color: #008000;">//insert</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        $entity = <span style="color: #0000ff;">new</span> entities\Student();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        $<span style="color: #0000ff;">this</span>-&gt;entityManager-&gt;persist($entity);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    }</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $<span style="color: #0000ff;">this</span>-&gt;addNewMarks($entity, $student); <span style="color: #008000;">//add new marks if any</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $entity-&gt;setFirstName($student-&gt;firstName);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $entity-&gt;setLastName($student-&gt;lastName);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $d = <span style="color: #0000ff;">new</span> DateTime();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $d-&gt;setTimestamp($student-&gt;registration-&gt;getTimestamp());</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $entity-&gt;setRegistration($d);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $country = $<span style="color: #0000ff;">this</span>-&gt;entityManager-&gt;find(<span style="color: #006080;">'entities\Country'</span>, $student-&gt;country-&gt;id);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #0000ff;">if</span> (!$country)</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> Exception(<span style="color: #006080;">'Error saving student; invalid country!'</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $entity-&gt;setCountry($country);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $<span style="color: #0000ff;">this</span>-&gt;entityManager-&gt;flush(); <span style="color: #008000;">//save the student</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">}</pre>
</div>
</div>
<p>If you think it is way to much code for this “simple” operation, then I think you are partially right. In the Conclusions section I touch on this. However you have to remember that this code handles many things: creating a new student, and inserting its marks in the Marks2 table or updating a student and its marks from the Marks2 table if they were changed (new courses added, grade changes and so on).</p>
<p>Instead the delete method is quite clean (remember that behind the scene removes all the related records from the marks many-to-many table):</p>
<div style="border: 1px solid gray; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text;">
<div style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> deleteStudent($student) {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $entity = $<span style="color: #0000ff;">this</span>-&gt;entityManager-&gt;find(<span style="color: #006080;">'entities\Student'</span>, $student-&gt;id);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #0000ff;">if</span> (!$entity)</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">        <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> Exception(<span style="color: #006080;">'Error deleting student!'</span>);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $<span style="color: #0000ff;">this</span>-&gt;entityManager-&gt;remove($entity);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    $<span style="color: #0000ff;">this</span>-&gt;entityManager-&gt;flush();</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">}</pre>
</div>
</div>
<h2>Getting the source code</h2>
<p>If you&#8217;re curious and you want to explore the code, you can download the project from <a href="http://corlan.org/downloads/students-doctrine2.fxp" target="_blank">here</a>. It contains the PHP <em>doctrine2_students</em> folder, the database SQL dump for creating the tables, and the Flex code.</p>
<p>The easiest way to import this project is just to extract the folders (you import the project in Flash Builder). Then place the PHP code (<em>doctrine2_students</em> folder) inside of the web root folder. Get the <a href="http://www.doctrine-project.org/projects/orm/download" target="_blank">Doctrine 2 files</a>, and then reconfigure the <em>doctrine2_students/bootstrap.php</em> file to define the Doctrine 2 location and update the database credential. And finally, create a new Flex/PHP project, and repeat the first part of the article (creating the Flex wrapper services and value objects).</p>
<h2>Conclusions</h2>
<p>Overall, I think Doctrine 2 makes it easier to work on PHP and Flex projects. I especially love the new Data Mapper approach and its flexibility/power. The entities are very light and you can easily use DQL in conjunction with <em>getArrayResult()</em> to build a data structure ready for sending to Flex. Also there is no need for all the plumbing work I did for Doctrine 1 in order to send the objects on the PHP side. I encourage you to read the excellent documentation you’ll find on Doctrine <a href="http://www.doctrine-project.org/projects/orm/2.0/docs/en" target="_blank">site</a> to better understand the inner workings, the different types of associations, and in general the features it offers.</p>
<p>With Doctrine 2 you get a big boost in terms of writing the PHP services and exposing the data to the Flex client. And if you think about it, the server side is not the place where the most the effort goes in. So it is a good thing to have a framework that standardize the PHP code and helps you big time when retrieving and persisting data. However, you can tell that it is not a framework architected with rich clients in mind (and there is nothing bad in this, I mean it’d be the same with the most of the frameworks out there). As easy it is retrieving data from the underlying persistence layer and sending them to a rich client, as hard persisting the client changes is. You have to write custom code to create the PHP entities out of the data received from the client before being able to persist the changes. What I feel it is missing is a way to use a data structure (for example an associative array) as the source for creating the PHP entities (more on this below).</p>
<p>Another interesting departure from the Doctrine 1 example is that I didn’t create an exact match between the ActionScript and PHP entities. When I designed the two sides of the equation, I had in mind the best domain model to serve the Flex client because all the information is edited on the client. Then I used the <em>getArrayResult()</em> method to send associative arrays to Flex (which are deserialized into Objects in Flex).</p>
<p>A feature I stayed away instinctively (both with Dotrine 1 and 2) was the ability to generate the database schema using the entities and the mapping between them. In other words, you could start your project first writing the PHP data model, and then use Doctrine to generate the database for you. I’m old school and all my experience taught me that relational databases treat you well if you treat them well. Thus, I much prefer to create the database with my “own” hands and make sure I set all the indexes/constraints I need. Having said this, I&#8217;m not saying that the Doctrine feature for generating database schema is buggy or worthless. I just wanted to explain why I haven’t tried. Your mileage could vary on this one.</p>
<p>The data-centric development features of Flash Builder simplified the creation of the data model a lot. I’m not sure if they work for any kind of project, but in this case I didn’t see any drawbacks.</p>
<p>You have very little work to do when handling the <em>Delete</em> and <em>Read</em> part of the <em>CRUD</em> operations on the server side. However, with <em>Create</em>/<em>Update</em> things change, especially when the object has associations (many-to-many, one-to-many, many-to-one with other entities). I thought it would be enough to retrieve the existing <em>Student</em> data from Doctrine and call the <em>removeMark()</em> method to remove a <em>Mark</em>. In fact, doing this doesn’t delete the entry from the many-to-many table. Instead, you have to explicitly remove the <em>Mark</em> instance from the <em>Student</em> and from the <em>entityManager</em>:</p>
<div style="border: 1px solid gray; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text;">
<div style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$student-&gt;removeMark($mark);</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">$<span style="color: #0000ff;">this</span>-&gt;entityManager-&gt;remove($mark);</pre>
</div>
</div>
<p>Doctrine 2 offers a Cascade feature for persist/remove. For example, here I defined cascade delete/update for the <em>Marks</em> entities on the <em>Student</em> object:</p>
<div style="border: 1px solid gray; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: consolas,'Courier New',courier,monospace; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text;">
<div style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #0000ff;">class</span> Student {</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">...</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #008000;">/**</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">    * @OneToMany(targetEntity="Mark", mappedBy="student", cascade={"persist", "remove"})</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;"><span style="color: #008000;">    */</span></pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">    <span style="color: #0000ff;">private</span> $marks;</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">...</pre>
<pre style="border-style: none; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; color: black; font-size: 8pt; overflow: visible;">}</pre>
</div>
</div>
<p>However, I found that they actually work perfectly only on delete (see the previous paragraph for why I don’t believe the persist is fully functional). It is possible that I didn’t understand the usage, and I was expecting more than intended or I just messed up something…</p>
<p>Another small glitch was related to the composite primary keys. When I tried to follow Doctrine’s documentation and annotate the <em>Mark</em> entity to compose the primary key out of <em>student_id</em> and <em>course_id</em>, I got a runtime error. So I had to alter the table and add an auto increment primary key.</p>
<p>The only other thing I didn’t like was the date handling. When you send a Date object to the PHP side, on the PHP side you get a Zend_Date object (when using the Zend Framework). And because Doctrine 2 knows how to handle only the PHP DateTime object, you have to manually handle the transformation. It would be cool to either configure in some way Zend Framework to use PHP DateTime instead of Zend_Date or to have Doctrine 2 handle this for you :D</p>
<p>I had tons of fun while writing this article and playing with this new technology. I can say that Doctrine 2 rocks! If you give Doctrine 2 a try with Flex, please drop a comment with your impressions.</p>
]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/08/05/working-with-doctrine-2-flex-zend-amf-and-flash-builder/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>Working with Doctrine 1.x, Zend Framework, and Flex</title>
		<link>http://corlan.org/2010/05/05/working-with-doctrine-zend-framework-and-flex/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=working-with-doctrine-zend-framework-and-flex</link>
		<comments>http://corlan.org/2010/05/05/working-with-doctrine-zend-framework-and-flex/#comments</comments>
		<pubDate>Wed, 05 May 2010 20:38:59 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://corlan.org/2010/05/05/working-with-doctrine-zend-framework-and-flex/</guid>
		<description><![CDATA[
			
				
			
		
Later Update: If you are looking for an article rather on Doctrine 2 than Doctrine 1, then check this one.
This year I finally had the time to play with Doctrine (version 1.x) and Flex. Actually, it was more than playing; I’m using it for a real project that hopefully will enter production pretty soon. To [...]]]></description>
			<content:encoded><![CDATA[<div class="none" style="float: right; margin-left: 10px;"><g:plusone href="http://corlan.org/2010/05/05/working-with-doctrine-zend-framework-and-flex/" size="tall" count="true"></g:plusone></div><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcorlan.org%2F2010%2F05%2F05%2Fworking-with-doctrine-zend-framework-and-flex%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F05%2F05%2Fworking-with-doctrine-zend-framework-and-flex%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Later Update: If you are looking for an article rather on Doctrine 2 than Doctrine 1, then check this <a href="http://corlan.org/2010/08/05/working-with-doctrine-2-flex-zend-amf-and-flash-builder/" target="_blank">one</a>.</p>
<p>This year I finally had the time to play with Doctrine (version 1.x) and Flex. Actually, it was more than playing; I’m using it for a real project that hopefully will enter production pretty soon. To summarize the experience in just a few words: it’s mind-blowing.</p>
<p>OK, I admit I may be exaggerating a little bit. Still, it is something that can change the way you build projects. Doctrine is an ORM (Object Relational Mapper) framework for PHP and it can really speed up the server side development when you have a lot of tables in your database.<br />
In this article, I explore how to work with Doctrine on the server side, Flex on the client side, and remoting to communicate between Flex and PHP (using the Zend Framework for remoting on the PHP side). I also want to share with you some tools and workflows that can save you some time. While most things are fairly straightforward there are a number of tips and tricks that you may find useful if you decide to go down this road. (I will show you how to use plain vanilla value objects and how to handle dates just to give you two examples. Why reinvent the wheel?)</p>
<p>The application I’m going to build in this article is simple but the workflow is the same one I used with a much more complex application. Having said that let’s start by understanding the big picture.</p>
<p><span id="more-1889"></span></p>
<p><a name="top"></a></p>
<ol>
<li><a href="#a">The Big Picture</a></li>
<li><a href="#b">Database Model</a></li>
<li><a href="#c">Installing Doctrine</a></li>
<li><a href="#d">Configure Doctrine and generate the model files</a></li>
<li><a href="#e">IDEs: Eclipse PDT and Flash Builder 4</a></li>
<li><a href="#f">Creating the PHP services and PHP value objects</a>
<ol>
<li><a href="#f1">Getting the countries and courses</a></li>
<li><a href="#f2">Creating the StudentsService service</a></li>
<li><a href="#f3">Handling Create, Update, and Delete with Doctrine</a></li>
</ol>
</li>
<li><a href="#g">Installing the Zend Framework</a></li>
<li><a href="#h">Setting up the gateway file</a></li>
<li><a href="#i">Creating the Flex front-end</a>
<ol>
<li><a href="#i1">Creating the ActionScript value objects</a></li>
<li><a href="#i2">Creating the UI</a></li>
</ol>
</li>
<li><a href="#j">Getting the source code</a></li>
<li><a href="#k">Conclusions</a></li>
</ol>
<h2>The Big Picture</h2>
<p>Let’s see how these different pieces come together and play nice with each other like one big happy family. Have a look at Figure 1. Yeah, this is what you’ll get if you follow this article.</p>
<p><img style="display: inline; border-width: 0px;" title="Figure 1. Architectural view" src="http://corlan.org/wp-content/uploads/2010/05/schema.png" border="0" alt="Figure 1. Architectural view" width="600" height="220" /></p>
<p>Breaking down Figure 1:</p>
<ul>
<li>On the right is a MySQL database to persist the data. You’ll see the data model in the next chapter.</li>
<li>On the PHP server I use Doctrine to manage the tables in the database. I use Doctrine features to generate the model classes out of the database structure.</li>
<li>On the PHP server I have a bunch of PHP services, which will be consumed from Flex using remoting. Typically for each table from the database there is a PHP class that provides, at a minimum, basic CRUD operations (Create/Read/Update/Delete).  These PHP services use the Doctrine model classes to read and persist the data. They are completely unaware of the database structure.</li>
<li>Finally, we have plain vanilla PHP value objects. These may follow the structure of the database. The Doctrine models return instances of these value objects. The PHP services, when called from the Flex side, receive instances of these classes as arguments.</li>
<li>The last piece on the PHP server is the Zend Framework. I use this framework to enable remoting for PHP (you could use AMFPHP, WebORB for PHP, or Sabre AMF as well). Basically it provides a gateway that represents the entry point to the PHP services for the Flex application.</li>
<li>On the Flex side there are RemoteObjects that map to the PHP services.</li>
<li>Then I have ActionScript value objects. For each PHP value object there is a corresponding ActionScript object. When using remoting the data is automatically changed to the right type based on the mappings you define.</li>
<li>I can bind these ActionScript value objects to the different user interface elements in my application.</li>
</ul>
<p><a name="a"></a>[<a href="#top">Top</a>]</p>
<h2>Database Model</h2>
<p>It is time to create the database. I’m going to use MySQL for the database. Every time I start a project that someday will be in production and uses a database I use data modeling software. Eight years ago the only viable solutions were Erwin or Power Designer (at least to my knowledge). I found that MySQL Workbench does a decent job and I use it fairly regularly nowadays (you can download MySQL Workbench from <a href="http://wb.mysql.com/" target="_blank">here</a>).</p>
<p>Why use  database modeling software? It helps you design the database and all the dependencies, share the design with others, and quickly remember the database structure when you go back to the project after couple of months off. And it helps you a lot when you start to change the project as you are in the middle of it. Remember that I’m talking about projects that go into production, and I think there are very few of those that don’t undergo modifications, including changes to the database structure.</p>
<p>You can use MySQL Workbench to create a data model from scratch or reverse engineer an existing database. You can push all the changes you make to the model (new tables/fields/indexes) directly to the database. And, of course, you can print these models.</p>
<p>To start a new model, choose File &gt; New and then click Add Diagram if you want to start from scratch. Then you can use the toolbox on the left to add tables and draw the relationships between them. When you double-click a table you can edit the name or add/edit fields and indexes. On the right side there is a Catalog viewer. By default the model will try to create the tables into a database named mydb. If you want to change the name of the database you can double-click on the current name from the Catalog view.</p>
<p>Once you’ve finished the design of the data model you can add a connection to your database server. The server can be on the localhost or a remote host, in the latter case you need to be careful if you have firewalls. Next use the Database &gt; Synchronize Model wizard to push the new database model to the database server. You can use the same wizard whether you make changes to the data model and need them reflected to the database or you change the database and you want to push them to the data model.</p>
<p>You can download the model I created (see Figure 2) from <a href="http://corlan.org/downloads/doctrine/db_model.mwb" target="_blank">here</a>.</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/05/figure_2.jpg"><img style="display: inline; border-width: 0px;" title="Figure 2. Creating the database" src="http://corlan.org/wp-content/uploads/2010/05/figure_2_thumb.jpg" border="0" alt="Figure 2. Creating the database" width="400" height="308" /></a></p>
<p>My application has four tables: students, countries, marks, and courses. A student can be registered to many courses and the mark (or grade) for each student for each course is stored in the marks table (a many-to-many table). Each student originates from a country, and there is a one-to-many relationship between the countries table and students table.</p>
<p>It is always a good practice to ensure that the data are consistent by using all the means a relational database offers (foreign keys, unique keys, and so on). I have unique keys for the name field in the countries and courses tables, on the first_name and last_name fields in the students table.</p>
<p>Now that I have the database in place and I can easy change it using the model, it is time to create the PHP classes that will handle these tables. Which means it is time for Doctrine to take the stage.</p>
<p>[<a href="#top">Top</a>]</p>
<h2>Installing Doctrine</h2>
<p><a name="c"></a></p>
<p>Doctrine is one of the few PHP ORMs (Object Relational Mapper) available. The current version (at the time of writing this article) is 1.2.2. You can download it from <a href="http://www.doctrine-project.org/download" target="_blank">here</a>. You can also get the library using SVN (<a href="http://svn.doctrine-project.org/tags/" target="_blank">here</a> is the link for the repository; you need to look under the tags node).</p>
<p>Why should you consider using Doctrine (or any other ORM for that matter)? Usually, any change you make at the database level will require a change to the PHP code that handles that database. Doctrine can isolate you from these changes. How? It has a feature that lets you generate PHP classes that handle each table from the database, and the input for this feature can be the database itself.</p>
<p>Suppose you add a new table and two new fields in existing tables. You do this in MySQL Workbench, then you use the MySQL Workbench synchronize feature to push all these changes to the database. Next you use Doctrine to generate again the PHP classes that handle this database. In just a couple of minutes you have all the code you need to perform CRUD operations on your tables.</p>
<p>Doctrine also takes care of escaping the values, thus protecting you from SQL injection attacks. Another cool feature of Doctrine is DQL (Doctrine Query Language). This feature makes it easy to write complete queries.</p>
<p>You may be thinking that using the layers on top of PHP (Doctrine and the Zend Framework) can degrade the performance of your application, including how fast it responds to a request, how many clients can connect, and so on. While this is true theoretically speaking, in practice I’d say that the vast majority of projects don’t have performance issues. They have problems keeping up with design changes and new features.</p>
<p>Once you have the library files, create a new folder called doctrine_students under your web root folder. Inside of this folder create these folders: lib, lib/vendor, and lib/vendor/doctrine/. Next copy the Doctrine files to the doctrine_students/ lib/vendor/doctrine/  folder. If you downloaded the archive file, then you have to copy the folders and files from Doctrine-1.2.2/Doctrine-1.2.2/lib/ (there should be a Doctrine.php file and a Doctrine folder).</p>
<p>You can read more about installing Doctrine <a href="http://www.doctrine-project.org/documentation/manual/1_1/hu/getting-started%3Aimplementing" target="_blank">here</a>.</p>
<p>[<a href="#top">Top</a>]</p>
<h2>Configure Doctrine and generate the model files</h2>
<p><a name="d"></a></p>
<p>The configuration of Doctrine is pretty simple. Basically you have to create a bootstrap file and include the Doctrine.php file, and then set the credentials for the database.</p>
<p>I created a file called bootstrap.php inside of the doctrine_students folder. This bootstrap file will be required in any PHP file that uses Doctrine. Inside of this file I added the following code:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&lt;?php</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #008000;">//require the main file from Doctrine</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">require_once(dirname(__FILE__) . <span style="color: #006080;">'/lib/vendor/doctrine/Doctrine.php'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #008000;">//register the class autoloader function</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">spl_autoload_register(array(<span style="color: #006080;">'Doctrine'</span>, <span style="color: #006080;">'autoload'</span>));</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #008000;">//create the singleton Doctrine_Manager instance</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">$manager = Doctrine_Manager::getInstance();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #008000;">// enable automatic queries resource freeing</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">$manager-&gt;setAttribute(Doctrine_Core::ATTR_AUTO_FREE_QUERY_OBJECTS, <span style="color: #0000ff;">true</span>);</pre>
</div>
</div>
<p>Next, create a new PHP file called generate_model.php inside of the doctrine_students folder and add this code as a simple test:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&lt;?php</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">require_once(<span style="color: #006080;">'bootstrap.php'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">echo Doctrine::getPath();</pre>
</div>
</div>
<p>If you navigate to the doctrine_students folder in a terminal/console window and run generate_model.php you should see the absolute path to the doctrine folder:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">mcorlan-mac:doctrine_students mcorlan$ php generate_model.php</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">/Applications/MAMP/htdocs/doctrine_students/lib/vendor/doctrinemcorlan-mac:doctrine_students mcorlan$</pre>
</div>
</div>
<p>Create a new folder called models inside of doctrine_students. This is where Doctrine will generate the model files. Then go back to bootstrap.php file and add a new line at the end to create a database connection:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #008000;">//create a connection</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">$conn = Doctrine_Manager::connection(<span style="color: #006080;">'mysql://mihai:mihai@127.0.0.1/students'</span>, <span style="color: #006080;">'doctrine'</span>);</pre>
</div>
</div>
<p>Basically you set the connection type to mysql, then you set the user and password (in my case “mihai” for both) then you set the database IP (don’t use localhost even if you have MySQL installed on your local machine because it will not work), and finally you specify the name of the database to be used.</p>
<p>Back in the generate_model.php file, comment out the echo line and add these lines:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #008000;">//generate the models from the DB schema in the models folder</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">Doctrine_Core::generateModelsFromDb(<span style="color: #006080;">'models'</span>, array(<span style="color: #006080;">'doctrine'</span>), array(<span style="color: #006080;">'generateTableClasses'</span> =&gt; <span style="color: #0000ff;">true</span>));</pre>
</div>
</div>
<p>In your console, run php generate_model.php and you should find in the doctrine_students/models/ folder a bunch of files and another folder named generated. Basically you have a file with the same name for each table from your database. You will see in the next chapter how to use these model files to persist and retrieve data.</p>
<p>Having generated the model files, I want to load them by adding these lines to the bootstrap file (at the end of the file):</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #008000;">//include the models</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">Doctrine_Core::loadModels(dirname(__FILE__) . <span style="color: #006080;">'/models/generated'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">Doctrine_Core::loadModels(dirname(__FILE__) . <span style="color: #006080;">'/models'</span>);</pre>
</div>
</div>
<p>Doctrine offers another way for creating these model files: YAML schema files. You can write a schema file from scratch and then use this file for generating the models. Alternative, you can use the models you generated using the database structure to create a schema file and then edit this file before using it to regenerate the models.</p>
<p>If you want to create a schema file, just edit the generate_model.php file as follows (I commented the line that generates the model from the database and I added a new line that creates a YAML file from the models):</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&lt;?php</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">require_once(<span style="color: #006080;">'bootstrap.php'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #008000;">//echo Doctrine::getPath();</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #008000;">//generate the models from the DB schema in the models folder</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #008000;">//Doctrine_Core::generateModelsFromDb('models', array('doctrine'), array('generateTableClasses' =&gt; true));</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #008000;">//generate the Doctrine Schema from models</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">Doctrine_Core::generateYamlFromModels(<span style="color: #006080;">'schema.yml'</span>, <span style="color: #006080;">'models'</span>);</pre>
</div>
</div>
<p>Return to the console and execute the following command again: php generated_model.php. After this you’ll find a schema.yml file inside of doctrine_students folder.</p>
<p>With all the models in place, it is time to see how you can use these files to manage the database.</p>
<p>[<a href="#top">Top</a>]</p>
<h2>IDEs: Eclipse PDT and Flash Builder 4</h2>
<p><a name="e"></a></p>
<p>Up until now you could have used just about any text editor to complete the steps I’ve outlined. As the code you write gets more complex (and soon you will start to write Flex code as well), it is time to introduce you to my favorite setup for working on Flex and PHP projects: Eclipse PDT + Flash Builder 4 plug-in + XDebug (for enabling PHP debugging).</p>
<p>The easiest way to install Eclipse PDT and Flash Builder together is to first grab the Eclipse PDT and then install the plug-in version of Flash Builder on top of  Eclipse PDT. You can read more about how to install these products together <a href="http://corlan.org/debugging-flex-and-php/#d" target="_blank">here</a>.</p>
<p>Now that you have support for both PHP and Flex projects, create a PHP project using the PHP new project wizard from Eclipse PDT (select the PHP perspective and choose File &gt; New &gt; PHP Project). I named the project students.</p>
<p>Then  add the doctrine_students folder to the project. Right-click the project name in Eclipse and choose New &gt; Folder. When the wizard opens, click the Advanced button and then select the Link To Folder In The File System option. Next, click Browse, select the doctrine_students folder, and click Finish (see Figure 3).</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/05/figure_3.jpg"><img style="display: inline; border-width: 0px;" title="Figure 3. Adding the doctrine_students folder to the project." src="http://corlan.org/wp-content/uploads/2010/05/figure_3_thumb.jpg" border="0" alt="Figure 3. Adding the doctrine_students folder to the project." width="300" height="268" /></a></p>
<p>Then create another two folders inside of doctrine_students folder: services and vo (see Figure 4).</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/05/figure_4.jpg"><img style="display: inline; border-width: 0px;" title="Figure 4. The students project in Eclipse" src="http://corlan.org/wp-content/uploads/2010/05/figure_4_thumb.jpg" border="0" alt="Figure 4. The students project in Eclipse" width="218" height="240" /></a></p>
<p>[<a href="#top">Top</a>]</p>
<h2>Creating the PHP Services and PHP value objects</h2>
<p><a name="f"></a></p>
<p>It is time to create the PHP services. I’ll use the model files that Doctrine generated earlier.</p>
<p>First I will create a PHP class with two methods: getCourses() and getCountries(). In many applications you have some tables that stores data that almost never changes, for example lists of countries or cities. For such tables, you don’t need to implement CRUD operations you just need the read method. This is the case with the courses and countries tables.</p>
<p>[<a href="#top">Top</a>]</p>
<h3>Getting the countries and courses</h3>
<p><a name="f1"></a></p>
<p>Create a file named CatalogService.php inside the doctrine_students/services/ folder and add this code:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&lt;?php</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">require_once(dirname(__FILE__) . <span style="color: #006080;">'/../bootstrap.php'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #0000ff;">class</span> CatalogService {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getCourses() {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        $q = Doctrine_Query::create()</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                -&gt;select(<span style="color: #006080;">'*'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                -&gt;from(<span style="color: #006080;">'Courses'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                -&gt;orderBy(<span style="color: #006080;">'name'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        $ret = $q-&gt;execute(<span style="color: #0000ff;">null</span>, Doctrine_Core::HYDRATE_ARRAY);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        <span style="color: #0000ff;">return</span> $ret;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getCountries() {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        $q = Doctrine_Query::create()</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                -&gt;select(<span style="color: #006080;">'*'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                -&gt;from(<span style="color: #006080;">'Countries'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                -&gt;orderBy(<span style="color: #006080;">'name'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        $ret = $q-&gt;execute(<span style="color: #0000ff;">null</span>, Doctrine_Core::HYDRATE_ARRAY);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #0000ff;">return</span> $ret;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">}</pre>
</div>
</div>
<p>If this is your first time using Doctrine you’ll probably find this code both strange and familiar at the same time.</p>
<p>As I said earlier, Doctrine offers a query language (DQL). You can learn more about DQL <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/dql-doctrine-query-language" target="_blank">here</a>. The code above uses DQL to retrieve all the records from the courses and countries tables. Some things to remember:</p>
<ul>
<li>When you set the from clause (for example, -&gt;from(‘Countries’)) you don’t specify the actual table name but the name of the model PHP class generated by Doctrine to manage that table. In this case it happens to have the same name and the first letter is capitalized.</li>
<li>DQL works with objects and generates objects or graphs of objects.</li>
<li>You can control the result format for a query by setting the second parameter of the execute() method on Doctrine_Query. I want to have the result sets as arrays or associative arrays. You could have your own hydration method or you could use one of the built-in <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/data-hydrators" target="_blank">hydrators</a>.</li>
<li>If you want to see the actual SQL that is executed you can call this method: $q-&gt;getSqlQuery().</li>
</ul>
<p>Add some records to the courses and countries tables or use this <a href="http://corlan.org/downloads/doctrine/students_db.sql" target="_blank">script</a> to create the database.</p>
<p>Now, you’re ready to test this code. Usually I do this before trying to connect to the PHP code from a Flex application. Just add some simple code at the top of this file in order to initialize the CatalogService object and call the two methods:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">$service = <span style="color: #0000ff;">new</span> CatalogService();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">print_r($service-&gt;getCourses());</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">print_r($service-&gt;getCountries());</pre>
</div>
</div>
<p>If you run CatalogService.php in the browser you should see  the courses and countries used in the two tables (see Figure 5).</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/05/figure_5.jpg"><img style="display: inline; border-width: 0px;" title="Figure 5. Testing the CatalogService class" src="http://corlan.org/wp-content/uploads/2010/05/figure_5_thumb.jpg" border="0" alt="Figure 5. Testing the CatalogService class" width="400" height="185" /></a></p>
<p>I have the first service in place, but I’m not entirely satisfied with the way my service works. I want to use some simple value objects to wrap each record instead of having an array of associative arrays like I have now.</p>
<p>I create two value objects called Country and Course in the doctrine_students/vo/ folder:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&lt;?php</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #008000;">//Country.php</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff;">class</span> Country {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">public</span> $id;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">public</span> $name;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">}</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&lt;?php</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #008000;">//Course.php</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff;">class</span> Course {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">public</span> $id;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">public</span> $name;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">}</pre>
</div>
</div>
<p>Now I just have to create a function that transforms the arrays I get from the Doctrine_Query object into arrays of value objects. You could achieve this by creating a custom hydration method or processing the result you get from the array hydration method.</p>
<p>Here’s how I did it. I created a function called  prepareForAMF that accepts two arguments. The first is the array you get using the Doctrine_Query object and the second is an array of objects to be used to wrap the associative array. From this array the function retrieves the types it has to use to transform the associative array into objects.</p>
<p>Here is the code for this function:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff;">function</span> prepareForAMF($data, $arrTypes) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">if</span> (count($data) == 0)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #0000ff;">return</span> $data;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    $ret = array();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    $substract = <span style="color: #0000ff;">false</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">if</span> (!array_key_exists(<span style="color: #006080;">'0'</span>, $data)) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        $data = array($data);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        $substract = <span style="color: #0000ff;">true</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">for</span> ($i=0; $i&lt;count($data); $i++) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        $o = <span style="color: #0000ff;">new</span> $arrTypes[0]();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        <span style="color: #0000ff;">foreach</span> ($data[$i] <span style="color: #0000ff;">as</span> $property =&gt; $value) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            $pproperty = strtolower($property);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">if</span> (!property_exists($o, $pproperty)) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                <span style="color: #0000ff;">continue</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #0000ff;">if</span> (array_key_exists($property, $arrTypes)) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #0000ff;">if</span> ($value == NULL) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                    $o-&gt;$property = array();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    <span style="color: #0000ff;">continue</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                $newArr = $arrTypes;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                $newArr[0] = $arrTypes[$property];</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                $o-&gt;$pproperty = prepareForAMF($value, $newArr);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            } <span style="color: #0000ff;">else</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                $o-&gt;$pproperty = $value;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        $ret[] = $o;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">if</span> ($substract)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        $ret = $ret[0];</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">return</span> $ret;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">}</pre>
</div>
</div>
<p>I chose to declare this function in the bootstrap.php file because this file is already included in all the PHP services.</p>
<p>Having this function defined I rewrote the methods from CatalogService like this:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getCourses() {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    $q = Doctrine_Query::create()</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            -&gt;select(<span style="color: #006080;">'*'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            -&gt;from(<span style="color: #006080;">'Courses'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            -&gt;orderBy(<span style="color: #006080;">'name'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    $ret = $q-&gt;execute(<span style="color: #0000ff;">null</span>, Doctrine_Core::HYDRATE_ARRAY);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    $ret = prepareForAMF($ret, array(0 =&gt; <span style="color: #006080;">'Course'</span>));</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">return</span> $ret;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">}</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getCountries() {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    $q = Doctrine_Query::create()</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            -&gt;select(<span style="color: #006080;">'*'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            -&gt;from(<span style="color: #006080;">'Countries'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            -&gt;orderBy(<span style="color: #006080;">'name'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    $ret = $q-&gt;execute(<span style="color: #0000ff;">null</span>, Doctrine_Core::HYDRATE_ARRAY);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    $ret = prepareForAMF($ret, array(0 =&gt; <span style="color: #006080;">'Country'</span>));</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">return</span> $ret;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">}</pre>
</div>
</div>
<p>Next you need to include the two value objects in the CatalogService.php class by adding these lines at the top of it:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">require_once(dirname(__FILE__) . <span style="color: #006080;">'/../vo/Country.php'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">require_once(dirname(__FILE__) . <span style="color: #006080;">'/../vo/Course.php'</span>);</pre>
</div>
</div>
<p>If you run CatalogService.php in the browser you’ll see the courses and countries are now listed as objects (see Figure 6).</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/05/figure_6.jpg"><img style="display: inline; border-width: 0px;" title="Figure 6. Using value objects in the CatalogService class." src="http://corlan.org/wp-content/uploads/2010/05/figure_6_thumb.jpg" border="0" alt="Figure 6. Using value objects in the CatalogService class." width="400" height="117" /></a></p>
<p><strong>Note:</strong> In Doctrine 2.0 (the upcoming version of Doctrine) support for plain vanilla value objects and for AMF remoting is planned and this trick/hack will not be needed. This is actually the reason why I didn’t bother to write my own hydration method. I’m planning to do a test run with the nightly builds soon.</p>
<p>[<a href="#top">Top</a>]</p>
<h3>Creating the StudentsService service</h3>
<p><a name="f2"></a></p>
<p>It is time to move on and create another service for the students and marks tables. Create a file inside of doctrine_students/services/ folder named StudentsService.php.</p>
<p>Here is a blue print of the StudentsService class:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&lt;?php</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">require_once(dirname(__FILE__) . <span style="color: #006080;">'/../bootstrap.php'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">require_once(dirname(__FILE__) . <span style="color: #006080;">'/../vo/Country.php'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">require_once(dirname(__FILE__) . <span style="color: #006080;">'/../vo/Course.php'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">$service = <span style="color: #0000ff;">new</span> StudentsService();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">print_r($service-&gt;getAll());</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff;">class</span> StudentsService {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getAll() {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> save($record) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> delete($record) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">}</pre>
</div>
</div>
<p>Let’s start by filling in the getAll() method. It will use the DQL feature to retrieve not only all the students, but also the country set for each student and all the marks he has (at this point you need to have some data in the students and marks tables):</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getAll() {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    $q = Doctrine_Query::create()</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                -&gt;select(<span style="color: #006080;">'s.*, m.*, c.*'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                -&gt;from(<span style="color: #006080;">'Students s'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                -&gt;leftJoin(<span style="color: #006080;">'s.Marks m'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                -&gt;leftJoin(<span style="color: #006080;">'s.Countries c'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                -&gt;orderBy(<span style="color: #006080;">'s.last_name, s.first_name'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        $ret = $q-&gt;execute(<span style="color: #0000ff;">null</span>, Doctrine_Core::HYDRATE_ARRAY);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #0000ff;">return</span> $ret;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">}</pre>
</div>
</div>
<p>Save the file and run it in the browser. If you choose view source you should see an array of arrays (see Figure 7).</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/05/figure_7.jpg"><img style="display: inline; border-width: 0px;" title="Figure 7. StudentsService getAll() method result " src="http://corlan.org/wp-content/uploads/2010/05/figure_7_thumb.jpg" border="0" alt="Figure 7. StudentsService getAll() method result " width="300" height="375" /></a></p>
<p>Notice that for each record from the students table I retrieve all the records from the marks table (student_id = id) and the country record  from the countries table (country_id = id). This works because Doctrine takes into account all the relations between the tables when it creates the models.</p>
<p>Because I defined a one-to-many relation between the countries and students tables (a country can be assigned to any number of students) and a many-to-many table (marks) between the students and courses tables (each student can have a mark for each course), Doctrine generated the model (schema.yml) and model classes to support this database schema. Indeed if you open the doctrine_students/schema.yml file and look at the Students entry you’ll see that it has defined two relations: Countries and Marks.</p>
<p>These two relations have the same name as the two fields you saw when you ran the StudentsService-&gt;getAll() method.</p>
<p>Next you’ll need to create two value objects (Student and Mark) to use with StudentsService. Add these two classes to the doctrine_students/vo/ folder:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&lt;?php</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #008000;">//Stundent.php file</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff;">class</span> Student {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">public</span> $id;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">public</span> $first_name;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">public</span> $last_name;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #0000ff;">public</span> $registration;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">public</span> $marks;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">public</span> $countries;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">}</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&lt;?php</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #008000;">//Mark.php file</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff;">class</span> Mark {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">public</span> $student_id;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">public</span> $course_id;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">public</span> $mark;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">}</pre>
</div>
</div>
<p>Don’t forget to include these two new classes in the StudentsService.php file.</p>
<p>Now I’ll change the getAll() method to transform the array I get from the Doctrine query into an array of value objects:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #008000;">//StundentsService class definition</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">...</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #0000ff;">private</span> $types = array (0 =&gt; <span style="color: #006080;">'Student'</span>, <span style="color: #006080;">'Countries'</span> =&gt; <span style="color: #006080;">'Country'</span>, <span style="color: #006080;">'Marks'</span> =&gt; <span style="color: #006080;">'Mark'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getAll() {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    $q = Doctrine_Query::create()</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            -&gt;select(<span style="color: #006080;">'s.*, m.*, c.*'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            -&gt;from(<span style="color: #006080;">'Students s'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            -&gt;leftJoin(<span style="color: #006080;">'s.Marks m'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            -&gt;leftJoin(<span style="color: #006080;">'s.Countries c'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            -&gt;orderBy(<span style="color: #006080;">'s.last_name, s.first_name'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        $ret = $q-&gt;execute(<span style="color: #0000ff;">null</span>, Doctrine_Core::HYDRATE_ARRAY);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        $ret = prepareForAMF($ret, $<span style="color: #0000ff;">this</span>-&gt;types);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #0000ff;">return</span> $ret;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">}</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">...</pre>
</div>
</div>
<p><strong>Note:</strong> The prepareForAMF function works recursively as long as you provide the right mapping between the keys of the arrays and the value objects it needs to create. This time I defined these mappings as a class variable ($types).</p>
<p>If you run the code again you should now see arrays of value objects: Student, Mark, and Country.</p>
<p>There’s something else I want to fix. The registration field from the students table has the Date type. But in the array returned by the getAll() method it is a String. I want to make sure that this field is actually an instance of the DateTime class. This will pay dividends later on when I retrieve these records in the Flex client, because it will receive value objects that have the Date type for the registration field instead of String.</p>
<p>The best place to do this transformation is probably inside the prepareForAMF() function. I added an optional third argument that is an array of the fields that have Date or DateTime type. So here is the modified function:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff;">function</span> prepareForAMF($data, $arrTypes, $arrDates=NULL) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">if</span> (count($data) == 0)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #0000ff;">return</span> $data;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    $ret = array();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    $substract = <span style="color: #0000ff;">false</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">if</span> (!array_key_exists(<span style="color: #006080;">'0'</span>, $data)) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        $data = array($data);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        $substract = <span style="color: #0000ff;">true</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">for</span> ($i=0; $i&lt;count($data); $i++) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        $o = <span style="color: #0000ff;">new</span> $arrTypes[0]();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        <span style="color: #0000ff;">foreach</span> ($data[$i] <span style="color: #0000ff;">as</span> $property =&gt; $value) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            $pproperty = strtolower($property);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">if</span> (!property_exists($o, $pproperty)) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                <span style="color: #0000ff;">continue</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #0000ff;">if</span> (array_key_exists($property, $arrTypes)) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #0000ff;">if</span> ($value == NULL) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                    $o-&gt;$pproperty = array();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    <span style="color: #0000ff;">continue</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                $newArr = $arrTypes;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                $newArr[0] = $arrTypes[$property];</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                $o-&gt;$pproperty = prepareForAMF($value, $newArr, $arrDates);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            } <span style="color: #0000ff;">else</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #0000ff;">if</span> ($arrDates &amp;&amp; array_key_exists($pproperty, $arrDates)) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                    $o-&gt;$pproperty = <span style="color: #0000ff;">new</span> DateTime($value);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                } <span style="color: #0000ff;">else</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                    $o-&gt;$pproperty = $value;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        $ret[] = $o;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">if</span> ($substract)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        $ret = $ret[0];</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">return</span> $ret;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">}</pre>
</div>
</div>
<p>Then I add a third argument when calling the prepareForAMF() function inside of getAll():</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #008000;">//StundentsService class definition</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">...</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff;">private</span> $dates = array(<span style="color: #006080;">'registration'</span> =&gt; 1);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getAll() {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    $q = Doctrine_Query::create()</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            -&gt;select(<span style="color: #006080;">'s.*, m.*, c.*'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            -&gt;from(<span style="color: #006080;">'Students s'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            -&gt;leftJoin(<span style="color: #006080;">'s.Marks m'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            -&gt;leftJoin(<span style="color: #006080;">'s.Countries c'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            -&gt;orderBy(<span style="color: #006080;">'s.last_name, s.first_name'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        $ret = $q-&gt;execute(<span style="color: #0000ff;">null</span>, Doctrine_Core::HYDRATE_ARRAY);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        $ret = prepareForAMF($ret, $<span style="color: #0000ff;">this</span>-&gt;types, $<span style="color: #0000ff;">this</span>-&gt;dates);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        <span style="color: #0000ff;">return</span> $ret;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">}</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">...</pre>
</div>
</div>
<p>[<a href="#top">Top</a>]</p>
<h3>Handling Create, Update, and Delete with Doctrine</h3>
<p><a name="f3"></a></p>
<p>It is time to write the StudentsService methods for creating, updating, and deleting records. For this, you need to fill in the blanks for the other two methods  defined earlier: save() and delete(). Please notice:</p>
<ul>
<li>I want to use the save() method for both creating new records and updating existing ones.</li>
<li>The save() method receives one argument: an instance of a Student value object. If you want to add marks for the student you have to have Mark objects stored in the mark property.</li>
<li>The save() method will add or change the related records from the marks table for the current student .</li>
<li>The delete() method deletes all the related records from the marks table first and then the student (it is transaction safe).</li>
</ul>
<p>Here is the code for save():</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> save($record) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        $record = makeArrayFromObject($record, $<span style="color: #0000ff;">this</span>-&gt;dates);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #008000;">//update an existent student</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        <span style="color: #0000ff;">if</span> ($record[<span style="color: #006080;">'id'</span>] &gt; 0) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #008000;">//retrieve the current student model</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            $o = Doctrine_Query::create()</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                -&gt;select(<span style="color: #006080;">'*'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                -&gt;from(<span style="color: #006080;">'Students'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                -&gt;where(<span style="color: #006080;">'id = ?'</span>, $record[<span style="color: #006080;">'id'</span>])</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                -&gt;fetchOne();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #0000ff;">if</span> (!$o)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span>; <span style="color: #008000;">//exit if there is no student</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #008000;">//loading relations</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            $o-&gt;Marks;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #008000;">//clean up the array</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            $record[<span style="color: #006080;">'Marks'</span>] = $record[<span style="color: #006080;">'marks'</span>];</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            unset($record[<span style="color: #006080;">'marks'</span>]);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">if</span> (array_key_exists(<span style="color: #006080;">'countries'</span>, $record)) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                <span style="color: #008000;">//set the country id</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                $o-&gt;country_id = $record[<span style="color: #006080;">'countries'</span>][0][<span style="color: #006080;">'id'</span>];</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                unset($record[<span style="color: #006080;">'countries'</span>]);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #008000;">//modify the existent student data </span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #008000;">//using the data we have in $record </span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            $o-&gt;synchronizeWithArray($record);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        <span style="color: #008000;">//insert a new student</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        } <span style="color: #0000ff;">else</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            $o = <span style="color: #0000ff;">new</span> Students();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #008000;">//load the main properties from the $record</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            $o-&gt;fromArray(cleanRefences($record, $<span style="color: #0000ff;">this</span>-&gt;types));</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #008000;">//add marks records for the student if any</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">if</span> ($record[<span style="color: #006080;">'marks'</span>]) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                <span style="color: #0000ff;">foreach</span> ($record[<span style="color: #006080;">'marks'</span>] <span style="color: #0000ff;">as</span> $val) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    $t = <span style="color: #0000ff;">new</span> Marks();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                    $t-&gt;fromArray($val);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    $o-&gt;Marks[] = $t;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #008000;">//setting student's country id</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">if</span> (array_key_exists(<span style="color: #006080;">'countries'</span>, $record) &amp;&amp; count($record[<span style="color: #006080;">'countries'</span>]) &gt; 0) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                $o-&gt;country_id = $record[<span style="color: #006080;">'countries'</span>][0][<span style="color: #006080;">'id'</span>];</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #008000;">//persist the data model to the database</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        $o-&gt;save();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #008000;">//loading Countries relations</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            $o-&gt;Countries;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        $ret = prepareForAMF($o-&gt;toArray(), $<span style="color: #0000ff;">this</span>-&gt;types, $<span style="color: #0000ff;">this</span>-&gt;dates);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">return</span> $ret;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    }</pre>
</div>
</div>
<p>And here is the code for two functions I use in the save() method (I declared these functions in the bootstrap.php file):</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff;">function</span> makeArrayFromObject($data, $arrDates=NULL)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">{</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    $data = (array)$data;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">foreach</span> ($data <span style="color: #0000ff;">as</span> $k =&gt; $v) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #0000ff;">if</span> (is_array($v)) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            $data[$k] = makeArrayFromObject($v, $arrDates);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        } <span style="color: #0000ff;">else</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">if</span> ($arrDates &amp;&amp; array_key_exists($k, $arrDates)) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                <span style="color: #0000ff;">if</span> ($v instanceof DateTime) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    $data[$k] = $v-&gt;format(<span style="color: #006080;">'Y-m-d'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                } <span style="color: #0000ff;">else</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    $data[$k] = $v-&gt;toString(<span style="color: #006080;">'Y-M-d'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            } <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (is_object($v)) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                $data[$k] = (array)$v;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">return</span> $data;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">}</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #0000ff;">function</span> cleanRefences($data, $references)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">{</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">foreach</span> ($references <span style="color: #0000ff;">as</span> $key =&gt; $val) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #0000ff;">if</span> (array_key_exists($key, $data)) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            $data[$key] = NULL;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">return</span> $data;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">}</pre>
</div>
</div>
<p>There are comments in the code so it should be easy to read and understand. I’ll explain just the parts I think are important:</p>
<ul>
<li>First of all, as I said earlier, Doctrine 1.x doesn’t have support for plain vanilla value objects. This is why the first thing I do is to transform the Student value object into an associative array using the makeArrayFromObject() function.</li>
<li>When I update an existing record I use DQL to create an instance of Students. Once I have the Students object for the given ID, I want to load all the related marks records (by calling $o-&gt;Marks). Next I use the synchronizeWithArray() method to apply the changes from the $record array to the existing data (basically synchronizeWithArray() receives an associative array similar in structure to the one you get when using the Array hydration method on the same object). Finally I set the country id, and once I call the save() method on the Students object ($o-&gt;save()) the data are persisted.</li>
<li>When I add a new record, I instantiate a Students object and then I use the fromArray() method to load the data from the $record array. However I found a glitch: for some reason it doesn’t work with the relations (in my case it didn’t save the related records to the marks table). So the workaround I found is to use the fromArray() method to load only the properties stored in the same table (students). This is why I clean the array from all the relations (Marks and Countries) using a call to the cleanReferences() function. I add the Marks objects manually using a for() loop.</li>
<li>When adding marks records, it is interesting to note that Doctrine takes care of all the plumbing work for me. Suppose you add a new student and at the same time two marks: (course_id:1, mark:10) and (course_id:3, mark:9). The marks table has a third field student_id. When you call the save() method on the Students object, Doctrine will insert a new record in the students table, it will retrieve the id and then fill in the missing student_id for the two Mark records and then insert these two records.</li>
</ul>
<p>The code for the delete() operation is much simpler. I use DQL to first delete all the related records from the marks table and then I delete the student record using an instance of Students. I make use of Doctrine support for transactions to keep the data consistent.</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #008000;">//StudentsService class definition</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">...</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> delete($record) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        $record = makeArrayFromObject($record, $<span style="color: #0000ff;">this</span>-&gt;dates);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #008000;">//delete all related records from marks table</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        $q = Doctrine_Query::create()</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                -&gt;delete(<span style="color: #006080;">'Marks'</span>)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                -&gt;where(<span style="color: #006080;">'student_id = ?'</span>, $record[<span style="color: #006080;">'id'</span>]);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #008000;">//start transaction        </span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            $q-&gt;getConnection()-&gt;beginTransaction();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            $q-&gt;execute();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        $o = <span style="color: #0000ff;">new</span> Students();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        $o-&gt;assignIdentifier($record[<span style="color: #006080;">'id'</span>]);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        $o-&gt;delete();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        $q-&gt;getConnection()-&gt;commit(); <span style="color: #008000;">//commit transaction</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        $ret = prepareForAMF($o-&gt;toArray(), $<span style="color: #0000ff;">this</span>-&gt;types, $<span style="color: #0000ff;">this</span>-&gt;dates);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">return</span> $ret;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">...</pre>
</div>
</div>
<p>You now have all the code in place. If you want to verify it you can add testing code (the lines below) in the StudentsService.php file. Then run the file in the browser and then check the database:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">$service = <span style="color: #0000ff;">new</span> StudentsService();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">$c = <span style="color: #0000ff;">new</span> Country();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">$c-&gt;id = 1;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">$m1 = <span style="color: #0000ff;">new</span> Mark();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">$m1-&gt;course_id = 3;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">$m1-&gt;mark = 7;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">$m2 = <span style="color: #0000ff;">new</span> Mark();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">$m2-&gt;course_id = 4;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">$m2-&gt;mark = 8;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">$s = <span style="color: #0000ff;">new</span> Student();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">$s-&gt;first_name = <span style="color: #006080;">'Michael'</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">$s-&gt;last_name = <span style="color: #006080;">'Doherty'</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">$s-&gt;registration = <span style="color: #0000ff;">new</span> DateTime(<span style="color: #006080;">'2010-03-14'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">$s-&gt;countries = $c;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">$s-&gt;marks = array($m1, $m2);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">print_r($service-&gt;save($s));</pre>
</div>
</div>
<p>Before moving on, don’t forget to comment (or delete) all the code you added in the service classes for testing.</p>
<p>[<a href="#top">Top</a>]</p>
<h2>Installing the Zend Framework</h2>
<p><a name="g"></a></p>
<p>The next task I have to complete on the PHP side is to enable support for remoting in PHP. I chose to do so by using the Zend Framework. You can use AMFPHP, WebORB for PHP, or SabreAMF as well.</p>
<p><a href="http://framework.zend.com/download" target="_blank">Download</a> and unzip the framework somewhere on your disk. Then use the php.ini file to include the framework:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">include_path = <span style="color: #006080;">".:/Applications/MAMP/bin/php5/lib/php:/Applications/MAMP/zend_framework/library "</span></pre>
</div>
</div>
<p>Save the file and restart the server. If you don’t have access to the php.ini you probably have to copy the whole framework under your web root, though this is not recommended for production.</p>
<p>[<a href="#top">Top</a>]</p>
<h2>Setting up the gateway file</h2>
<p><a name="h"></a></p>
<p>The last step I have to complete on the PHP side before moving to Flex is to create the gateway file. This file will represent the end point for all the remoting calls from the Flex application. It will configure and start the Zend AMF server.</p>
<p>Create a new file called gateway.php inside of doctrine_students folder and then add this code:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&lt;?php</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">require_once(<span style="color: #006080;">'Zend/Amf/Server.php'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #008000;">//create an instance of Zend AMF server</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">$server = <span style="color: #0000ff;">new</span> Zend_Amf_Server();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #008000;">//adding the services folder in order to expose</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #008000;">//CatalogService and StudentsService</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">$server-&gt;addDirectory(dirname(__FILE__) . <span style="color: #006080;">'/services/'</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: #008000;">//Mapping the ActionScript VO to the PHP VO</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #008000;">//you don't have to add the package name</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">$server-&gt;setClassMap(<span style="color: #006080;">"Country"</span>, <span style="color: #006080;">"Country"</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">$server-&gt;setClassMap(<span style="color: #006080;">"Course"</span>, <span style="color: #006080;">"Course"</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">$server-&gt;setClassMap(<span style="color: #006080;">"Mark"</span>, <span style="color: #006080;">"Mark"</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">$server-&gt;setClassMap(<span style="color: #006080;">"Student"</span>, <span style="color: #006080;">"Student"</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">$server-&gt;setProduction(<span style="color: #0000ff;">false</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">echo($server -&gt; handle());</pre>
</div>
</div>
<p>Save the file and run it in the browser. You should either see the message “Zend Amf Endpoint” or a save dialog.</p>
<p>[<a href="#top">Top</a>]</p>
<h2>Creating the Flex front-end</h2>
<p><a name="i"></a></p>
<p>With all the PHP code in place, it is time to create the Flex front-end. From a workflow perspective you have two options:</p>
<ul>
<li>You can create a separate Flex project and have two projects in place: one for Flex and one for PHP.</li>
<li>You can add Flex nature to the PHP project and use the same project for both Flex and PHP.</li>
</ul>
<p>I usually prefer the second approach because I work on both Flex and PHP code and it is simple to debug them together.</p>
<p>To add Flex nature to the students project, right-click on the project name in Eclipse, and select Add/Change Project Type &gt; Add Flex Project Type. When the wizard opens, select PHP as the application server type and click Next. Fill in the path to the web server root and URL to reach the root, then click Validate Configuration and then Finish. You might see this error in the Problems view: “Cannot create HTML wrapper. Right-click here to recreate folder html-template.” Just right-click on it and choose Recreate Folder HTML-template.</p>
<p>This wizard will create an MXML file named students.mxml as well. Open this file if you haven’t already and add the following code inside the &lt;fx:Declarations&gt; tag:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&lt;s:RemoteObject id=<span style="color: #006080;">"catalogService"</span> source=<span style="color: #006080;">"CatalogService"</span> destination=<span style="color: #006080;">"zend"</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                endpoint=<span style="color: #006080;">"../doctrine_students/gateway.php"</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                result=<span style="color: #006080;">"onResult(event)"</span> fault=<span style="color: #006080;">"onFault(event)"</span>&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    &lt;s:method name=<span style="color: #006080;">"getCourses"</span> /&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    &lt;s:method name=<span style="color: #006080;">"getCountries"</span> /&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">&lt;/s:RemoteObject&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">&lt;s:RemoteObject id=<span style="color: #006080;">"studentsService"</span> source=<span style="color: #006080;">"StudentsService"</span> destination=<span style="color: #006080;">"zend"</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                endpoint=<span style="color: #006080;">"../doctrine_students/gateway.php"</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                result=<span style="color: #006080;">"onResult(event)"</span> fault=<span style="color: #006080;">"onFault(event)"</span>&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    &lt;s:method name=<span style="color: #006080;">"getAll"</span> /&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    &lt;s:method name=<span style="color: #006080;">"save"</span> /&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    &lt;s:method name=<span style="color: #006080;">"delete"</span> /&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">&lt;/s:RemoteObject&gt;</pre>
</div>
</div>
<p>The code defines two remoteObjects, one for each service on the PHP side: CatalogService and StudentsService. I added the methods for clarity, although this is not mandatory. Note that the endpoint attribute points to the gateway.php file  created earlier.</p>
<p>The next step is to define the onResult and onFault event listeners. Add this code above or below the &lt;fx:Declaration&gt; tag:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&lt;fx:Script&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    &lt;![CDATA[</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        import mx.rpc.events.FaultEvent;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        import mx.rpc.events.ResultEvent;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> onResult(e:ResultEvent):<span style="color: #0000ff;">void</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> onFault(e:FaultEvent):<span style="color: #0000ff;">void</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    ]]&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
</div>
</div>
<p>To test the code you’ll need to add a button and call one of the service’s methods on click. Next, add two breakpoints on the first line where each event listener is defined and then run the project in debug mode.</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">"catalogService.getCourses()"/></pre>
</div>
</div>
<p>After the page loads, click the button and in Eclipse you should see the Flex debugger stopped (see Figure 8).</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/05/figure_8.jpg"><img style="display: inline; border-width: 0px;" title="Figure 8. Testing the services in the Flex client using the Flex debugger." src="http://corlan.org/wp-content/uploads/2010/05/figure_8_thumb.jpg" border="0" alt="Figure 8. Testing the services in the Flex client using the Flex debugger." width="400" height="318" /></a></p>
<p>[<a href="#top">Top</a>]</p>
<h3>Creating the ActionScript value objects</h3>
<p><a name="i1"></a></p>
<p>When using remoting it is usually a good idea to create value objects on the Flex side that correspond to the value objects you have on the server side. In my case I need to create four value objects: Student, Mark, Course, and Country. I place all these classes in the org.corlan.vo package.</p>
<p>The code is here:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; height: 304px; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">package org.corlan.vo {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    [Bindable]</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    [RemoteClass(alias=<span style="color: #006080;">"Country"</span>)]</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Country {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">var</span> id:<span style="color: #0000ff;">int</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">var</span> name:String;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">}</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">package org.corlan.vo {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    [Bindable]</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    [RemoteClass(alias=<span style="color: #006080;">"Course"</span>)]</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Course {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">var</span> id:<span style="color: #0000ff;">int</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">var</span> name:String;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">}</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">package org.corlan.vo {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    [Bindable]</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    [RemoteClass(alias=<span style="color: #006080;">"Mark"</span>)]</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Mark {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">var</span> student_id:<span style="color: #0000ff;">int</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">var</span> course_id:<span style="color: #0000ff;">int</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">var</span> mark:Number;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">}</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">package org.corlan.vo {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    [Bindable]</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    [RemoteClass(alias=<span style="color: #006080;">"Student"</span>)]</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Student {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">var</span> id:<span style="color: #0000ff;">int</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">var</span> first_name:String;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">var</span> last_name:String;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">var</span> registration:Date;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">var</span> countries:Country;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">var</span> _marks:Array;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> get marks():Array {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">return</span> _marks;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> set marks(value:Array):<span style="color: #0000ff;">void</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i:<span style="color: #0000ff;">int</span>=0; i</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                value[i] = value[i] <span style="color: #0000ff;">as</span> Mark;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            _marks = value;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">}</pre>
</div>
</div>
<p>There is nothing special to these value object classes. I’m using the Bindable metadata to make each property <em>bindable</em> and I use the RemoteClass metadata to tell AMF which is the corresponding class on the server side. On the PHP side I have the mapping defined inside of the gateway.php file using the setClassMap() method from AMF server - $server->setClassMap("Country", "Country");.</p>
<p>For the Student value object I use the getter/setter to cast the array of objects received from the server to an array of Mark value objects.</p>
<p>Before testing the code you need to make sure that these four value object classes are included in the compiled SWF. You can simply add these lines in the students.mxml file:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">import org.corlan.vo.*;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">var</span> clz:Array = [Country, Course, Mark, Student];</pre>
</div>
</div>
<p>If you run the project and call the studentsService.getAll() method when clicking on the button, you should see the value objects in the Flex debugger (see Figure 9).</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/05/figure_9.jpg"><img style="display: inline; border-width: 0px;" title="Figure 9. Using value objects on the Flex side." src="http://corlan.org/wp-content/uploads/2010/05/figure_9_thumb.jpg" border="0" alt="Figure 9. Using value objects on the Flex side." width="400" height="297" /></a></p>
<p>[<a href="#top">Top</a>]</p>
<h3>Creating the UI</h3>
<p><a name="i2"></a></p>
<p>Now you can focus on the UI of this application. It will be a simple UI with a data grid for displaying all the students (see Figure 10). When a student is selected from the data grid, the form on the right is populated and you can use it to change details for the current student. If you want to delete a student, just select a row and click Delete. If you want to add a new record, click New and then fill in the form.</p>
<p>I have a function that is used for creating the text in the courses column, and a bunch of arrays I’m using to store the data models (courses, countries, and students).</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/05/figure_10.jpg"><img style="display: inline; border-width: 0px;" title="Figure 10. The Flex client." src="http://corlan.org/wp-content/uploads/2010/05/figure_10_thumb.jpg" border="0" alt="Figure 10. The Flex client." width="400" height="195" /></a></p>
<p>Here is the code for the application:</p>
<div style="border: 1px solid gray; padding: 4px; font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; height: 481px; background-color: #f4f4f4; max-height: 200px;">
<div style="padding: 0px; font-size: 8pt; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">"1.0" encoding=<span style="color: #006080;">"utf-8"</span>?></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">"http://ns.adobe.com/mxml/2009"</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">               xmlns:s=<span style="color: #006080;">"library://ns.adobe.com/flex/spark"</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">               xmlns:mx=<span style="color: #006080;">"library://ns.adobe.com/flex/mx"</span> minWidth=<span style="color: #006080;">"955"</span> minHeight=<span style="color: #006080;">"600"</span> creationComplete=<span style="color: #006080;">"init()"</span> xmlns:vo=<span style="color: #006080;">"org.corlan.vo.*"</span>></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <!--[CDATA[</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            import flash.sampler.NewObjectSample;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            import mx.collections.ArrayCollection;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            import mx.controls.Alert;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            import mx.events.ListEvent;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            import mx.rpc.AbstractOperation;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            import mx.rpc.events.FaultEvent;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            import mx.rpc.events.ResultEvent;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            import mx.rpc.remoting.Operation;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            import org.corlan.vo.*;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #0000ff;" mce_style="color: #0000ff;">static</span> <span style="color: #0000ff;" mce_style="color: #0000ff;">public</span> <span style="color: #0000ff;" mce_style="color: #0000ff;">var</span> clz:Array = [Country, Course, Mark, Student]-->
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            [Bindable]</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">var</span> arrStudents:ArrayCollection;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            [Bindable]</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">var</span> arrCourses:ArrayCollection;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            [Bindable]</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">var</span> arrCountries:ArrayCollection;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">var</span> coursesHash:Object;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">var</span> marks:Array;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> init():<span style="color: #0000ff;">void</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                catalogService.getCourses();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                catalogService.getCountries();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> getStudents():<span style="color: #0000ff;">void</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                studentsService.getAll();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> onStudents(e:ResultEvent):<span style="color: #0000ff;">void</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                arrStudents = <span style="color: #0000ff;">new</span> ArrayCollection(e.result <span style="color: #0000ff;">as</span> Array);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> onCourses(e:ResultEvent):<span style="color: #0000ff;">void</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                arrCourses = <span style="color: #0000ff;">new</span> ArrayCollection(e.result <span style="color: #0000ff;">as</span> Array);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #008000;">//save the courses into a hashmap</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                <span style="color: #0000ff;">var</span> l:<span style="color: #0000ff;">int</span> = arrCourses.length;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                coursesHash = <span style="color: #0000ff;">new</span> Object();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                marks = <span style="color: #0000ff;">new</span> Array();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #0000ff;">var</span> c:Course;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i:<span style="color: #0000ff;">int</span> = 0; i</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    c = (arrCourses[i] <span style="color: #0000ff;">as</span> Course);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                    coursesHash

[/c]

 = c.name;
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    marks.push({course_id : c.id, mark : 0, name : c.name});</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                dgMarks.dataProvider = marks;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> onCountries(e:ResultEvent):<span style="color: #0000ff;">void</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                arrCountries = <span style="color: #0000ff;">new</span> ArrayCollection(e.result <span style="color: #0000ff;">as</span> Array);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> onFault(e:FaultEvent):<span style="color: #0000ff;">void</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                Alert.show(e.fault.faultDetail, <span style="color: #006080;">"Error!"</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> onSelection(e:ListEvent):<span style="color: #0000ff;">void</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                student = e.itemRenderer.data <span style="color: #0000ff;">as</span> Student;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                <span style="color: #0000ff;">if</span> (student.countries) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    <span style="color: #0000ff;">var</span> l:<span style="color: #0000ff;">int</span> = arrCountries.length;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                    <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i:<span style="color: #0000ff;">int</span> = 0; i&lt;l; i++) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                        <span style="color: #0000ff;">if</span> (arrCountries[i].id == student.countries.id) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                            country.selectedIndex = i;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                            <span style="color: #0000ff;">break</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                        }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                <span style="color: #0000ff;">if</span> (student.marks &amp;&amp; student.marks.length &gt; 0) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    <span style="color: #0000ff;">var</span> k:<span style="color: #0000ff;">int</span> = marks.length;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                    <span style="color: #0000ff;">var</span> o:Object;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> j:<span style="color: #0000ff;">int</span> = 0; j&lt;k; j++) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                        o = marks[j];</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                        o[<span style="color: #006080;">"mark"</span>] = 0;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                        <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> jj:<span style="color: #0000ff;">int</span> = 0; jj &lt; student.marks.length; jj++) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                            <span style="color: #0000ff;">if</span> (student.marks[jj].course_id == o[<span style="color: #006080;">"course_id"</span>]) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                                o[<span style="color: #006080;">"mark"</span>] = student.marks[jj].mark;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                                <span style="color: #0000ff;">break</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                        }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    dgMarks.dataProvider = marks;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> customLabel(data:Object, column:DataGridColumn):String {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                <span style="color: #0000ff;">var</span> arr:Array = <span style="color: #0000ff;">new</span> Array();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #0000ff;">var</span> c:<span style="color: #0000ff;">int</span> = (data <span style="color: #0000ff;">as</span> Student).marks.length;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                <span style="color: #0000ff;">var</span> mark:Mark;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i:<span style="color: #0000ff;">int</span> = 0; i&lt;c; i++) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                    mark = (data <span style="color: #0000ff;">as</span> Student).marks[i];</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    arr.push(coursesHash[mark.course_id]);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #0000ff;">return</span> arr.join(<span style="color: #006080;">", "</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> saveStudent():<span style="color: #0000ff;">void</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #008000;">//set the marks</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                <span style="color: #0000ff;">var</span> l:<span style="color: #0000ff;">int</span> = marks.length;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #0000ff;">var</span> m:Mark;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                student.marks = <span style="color: #0000ff;">new</span> Array();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i:<span style="color: #0000ff;">int</span> = 0; i&lt;l; i++) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                    <span style="color: #0000ff;">if</span> (marks[i][<span style="color: #006080;">"mark"</span>] &gt; 0) {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                        m = <span style="color: #0000ff;">new</span> Mark();</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                        m.course_id = marks[i][<span style="color: #006080;">"course_id"</span>];</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                        m.mark = marks[i][<span style="color: #006080;">"mark"</span>];</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                        <span style="color: #0000ff;">if</span> (student.id &gt; 0)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                            m.student_id = student.id;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                        student.marks.push(m);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #008000;">//set the country</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                student.countries = country.selectedItem <span style="color: #0000ff;">as</span> Country;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #008000;">//set the names and registration date</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                student.first_name = first.text;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                student.last_name = last.text;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                student.registration = registration.selectedDate;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                studentsService.save(student);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span> deleteStudent():<span style="color: #0000ff;">void</span> {</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #0000ff;">if</span> (!student || !student.id)</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                    <span style="color: #0000ff;">return</span>;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                <span style="color: #0000ff;">var</span> o:AbstractOperation = studentsService.getOperation(<span style="color: #006080;">"delete"</span>);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                o.send(student);</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            }</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        ]]&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    &lt;/fx:Script&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    &lt;fx:Declarations&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        &lt;s:RemoteObject id=<span style="color: #006080;">"catalogService"</span> source=<span style="color: #006080;">"CatalogService"</span> destination=<span style="color: #006080;">"zend"</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                        endpoint=<span style="color: #006080;">"../doctrine_students/gateway.php"</span> fault=<span style="color: #006080;">"onFault(event)"</span>&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            &lt;s:method name=<span style="color: #006080;">"getCourses"</span> result=<span style="color: #006080;">"onCourses(event)"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            &lt;s:method name=<span style="color: #006080;">"getCountries"</span> result=<span style="color: #006080;">"onCountries(event)"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        &lt;/s:RemoteObject&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        &lt;s:RemoteObject id=<span style="color: #006080;">"studentsService"</span> source=<span style="color: #006080;">"StudentsService"</span> destination=<span style="color: #006080;">"zend"</span></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                        endpoint=<span style="color: #006080;">"../doctrine_students/gateway.php"</span> fault=<span style="color: #006080;">"onFault(event)"</span>&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            &lt;s:method name=<span style="color: #006080;">"getAll"</span> result=<span style="color: #006080;">"onStudents(event)"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            &lt;s:method name=<span style="color: #006080;">"save"</span> result=<span style="color: #006080;">"getStudents()"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            &lt;s:method name=<span style="color: #006080;">"delete"</span> result=<span style="color: #006080;">"getStudents()"</span> /&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        &lt;/s:RemoteObject&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        &lt;vo:Student id=<span style="color: #006080;">"student"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    &lt;/fx:Declarations&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    &lt;mx:DataGrid id=<span style="color: #006080;">"dgStudents"</span> dataProvider=<span style="color: #006080;">"{arrStudents}"</span> x=<span style="color: #006080;">"13"</span> y=<span style="color: #006080;">"14"</span> itemClick=<span style="color: #006080;">"onSelection(event)"</span>&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        &lt;mx:columns&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            &lt;mx:DataGridColumn headerText=<span style="color: #006080;">"First"</span> dataField=<span style="color: #006080;">"first_name"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            &lt;mx:DataGridColumn headerText=<span style="color: #006080;">"Last"</span> dataField=<span style="color: #006080;">"last_name"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            &lt;mx:DataGridColumn headerText=<span style="color: #006080;">"Country"</span> dataField=<span style="color: #006080;">"countries.name"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            &lt;mx:DataGridColumn headerText=<span style="color: #006080;">"Courses"</span> labelFunction=<span style="color: #006080;">"customLabel"</span> width=<span style="color: #006080;">"200"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        &lt;/mx:columns&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    &lt;/mx:DataGrid&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    &lt;s:Button click=<span style="color: #006080;">"getStudents()"</span> label=<span style="color: #006080;">"Get Students"</span> x=<span style="color: #006080;">"13"</span> y=<span style="color: #006080;">"200"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    &lt;s:Button x=<span style="color: #006080;">"112"</span> y=<span style="color: #006080;">"200"</span> label=<span style="color: #006080;">"New"</span> click=<span style="color: #006080;">"student = new Student();"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    &lt;s:Button x=<span style="color: #006080;">"190"</span> y=<span style="color: #006080;">"200"</span> label=<span style="color: #006080;">"Delete"</span> click=<span style="color: #006080;">"deleteStudent()"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    &lt;mx:Form x=<span style="color: #006080;">"510"</span> y=<span style="color: #006080;">"0"</span>&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        &lt;mx:FormItem label=<span style="color: #006080;">"First:"</span>&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            &lt;s:TextInput id=<span style="color: #006080;">"first"</span> text=<span style="color: #006080;">"{student.first_name}"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        &lt;/mx:FormItem&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        &lt;mx:FormItem label=<span style="color: #006080;">"Last:"</span>&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            &lt;s:TextInput id=<span style="color: #006080;">"last"</span> text=<span style="color: #006080;">"{student.last_name}"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        &lt;/mx:FormItem&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        &lt;mx:FormItem label=<span style="color: #006080;">"Registration:"</span>&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            &lt;mx:DateField id=<span style="color: #006080;">"registration"</span> selectedDate=<span style="color: #006080;">"{student.registration}"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        &lt;/mx:FormItem&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        &lt;mx:FormItem label=<span style="color: #006080;">"Country:"</span>&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            &lt;s:List id=<span style="color: #006080;">"country"</span> dataProvider=<span style="color: #006080;">"{arrCountries}"</span> labelField=<span style="color: #006080;">"name"</span> height=<span style="color: #006080;">"70"</span>&gt;&lt;/s:List&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        &lt;/mx:FormItem&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        &lt;mx:FormItem label=<span style="color: #006080;">"Marks:"</span>&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            &lt;mx:DataGrid id=<span style="color: #006080;">"dgMarks"</span> editable=<span style="color: #006080;">"true"</span>&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                &lt;mx:columns&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                    &lt;mx:DataGridColumn headerText=<span style="color: #006080;">"Course"</span> dataField=<span style="color: #006080;">"name"</span> editable=<span style="color: #006080;">"false"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">                    &lt;mx:DataGridColumn headerText=<span style="color: #006080;">"Mark"</span> dataField=<span style="color: #006080;">"mark"</span> editable=<span style="color: #006080;">"true"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">                &lt;/mx:columns&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            &lt;/mx:DataGrid&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">        &lt;/mx:FormItem&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        &lt;mx:FormItem&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">            &lt;s:Button label=<span style="color: #006080;">"Save"</span> click=<span style="color: #006080;">"saveStudent()"</span>/&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        &lt;/mx:FormItem&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">    &lt;/mx:Form&gt;</pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"></pre>
<pre style="padding: 0px; font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; border-style: none; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">&lt;/s:Application&gt;</pre>
</div>
</div>
<p>[<a href="#top">Top</a>]</p>
<h2>Getting the source code</h2>
<p><a name="j"></a></p>
<p>If you want to have a look at the project files here are the links:</p>
<ul>
<li>The doctrine_students folder is <a href="http://corlan.org/downloads/doctrine/doctrine_students.zip" target="_blank">here</a>. It includes the Doctrine framework, the gateway.php and bootstrap.php files, the models, services, and value object classes.</li>
<li>From <a href="http://corlan.org/downloads/doctrine/src.zip" target="_blank">here</a> you can download the source folder of the Flex project (you need the Flex 4 SDK to compile it).</li>
<li>Use this <a href="http://corlan.org/downloads/doctrine/students_db.sql" target="_blank">script</a> to create the database and populate it with some data.</li>
<li>You can find the MySQL Workbench model file <a href="http://corlan.org/downloads/doctrine/students_db.sql" target="_blank">here</a>.</li>
</ul>
<p>[<a href="#top">Top</a>]</p>
<h2>Conclusions</h2>
<p><a name="k"></a></p>
<p>In my experience, a software application is pretty much like a living thing: it grows and changes over time. Having some help along the way to make these changes smoother, reduce hand-coding, and minimize the potential for injecting bugs can make a big difference.</p>
<p>I think using an ORM framework on the server and letting this framework do the heavy lifting (generating the models based on the database structure, escaping the values to protect against SQL injection, making it easy to create a complex domain model, and making it easy to create CRUD services) is something that you may want to consider for your next project. These capabilities are especially helpful in the world of rich Internet applications where an important part of the business application stays on the client’s machine.</p>
<p>The only drawback I see with the current version of Doctrine (1.x) is that it needs some boiler plate code in order to make it possible to work with remoting and Flex. You can tweak the framework even more to make it generate the value objects as well. It seems the next version of Doctrine will make this integration much easier, and I plan to check this out soon :).</p>
<p>Until next time, please drop a comment and share your experience with PHP ORMs and using them with Flex.</p>
<p>[<a href="#top">Top</a>]</p>
]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/05/05/working-with-doctrine-zend-framework-and-flex/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>White Paper: debugging Flex and PHP projects</title>
		<link>http://corlan.org/2010/03/24/white-paper-debugging-flex-and-php-projects/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=white-paper-debugging-flex-and-php-projects</link>
		<comments>http://corlan.org/2010/03/24/white-paper-debugging-flex-and-php-projects/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 13:39:33 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1785</guid>
		<description><![CDATA[
			
				
			
		
I&#8217;ve just published a white paper on debugging Flex and PHP projects using Flash Builder 4, Eclipse PDT, and XDebug. You can read the article here.
In case you want to watch the webinar I did on the same subject today, you can go here. Thank you to all the people who joined my webinar!
PS. It [...]]]></description>
			<content:encoded><![CDATA[<div class="none" style="float: right; margin-left: 10px;"><g:plusone href="http://corlan.org/2010/03/24/white-paper-debugging-flex-and-php-projects/" size="tall" count="true"></g:plusone></div><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcorlan.org%2F2010%2F03%2F24%2Fwhite-paper-debugging-flex-and-php-projects%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F03%2F24%2Fwhite-paper-debugging-flex-and-php-projects%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;ve just published a white paper on debugging Flex and PHP projects using Flash Builder 4, Eclipse PDT, and XDebug. You can read the article <a href="http://corlan.org/debugging-flex-and-php/" target="_self">here</a>.</p>
<p>In case you want to watch the webinar I did on the same subject today, you can go <a href="http://my.adobe.acrobat.com/p38949820/" target="_blank">here</a>. Thank you to all the people who joined my webinar!</p>
<p>PS. It seems we&#8217;ve come a long way when it comes to writing Flex applications. Out of 250+ registered people, only 60 decided to drop by. This is really good news, soon there will be no more bugs in our software :D</p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/03/24/white-paper-debugging-flex-and-php-projects/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Debugging Flex and PHP projects webinar</title>
		<link>http://corlan.org/2010/03/22/debugging-flex-and-php-projects-webinar/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=debugging-flex-and-php-projects-webinar</link>
		<comments>http://corlan.org/2010/03/22/debugging-flex-and-php-projects-webinar/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 13:32:24 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1716</guid>
		<description><![CDATA[
			
				
			
		
We&#8217;ve just launched Flash Builder 4, our latest IDE for building RIAs with Flex and ActionScript. If you use PHP on the server side, you may want to join my webinar on Debugging Flex and PHP projects.

I will talk about the new features of Flash Builder 4 that can help you while debugging and I [...]]]></description>
			<content:encoded><![CDATA[<div class="none" style="float: right; margin-left: 10px;"><g:plusone href="http://corlan.org/2010/03/22/debugging-flex-and-php-projects-webinar/" size="tall" count="true"></g:plusone></div><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcorlan.org%2F2010%2F03%2F22%2Fdebugging-flex-and-php-projects-webinar%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F03%2F22%2Fdebugging-flex-and-php-projects-webinar%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>We&#8217;ve just launched Flash Builder 4, our latest IDE for building RIAs with Flex and ActionScript. If you use PHP on the server side, you may want to join my webinar on Debugging Flex and PHP projects.</p>
<p><img class="alignnone size-full wp-image-1718" title="xdebug_fb4" src="http://corlan.org/wp-content/uploads/2010/03/xdebug_fb4.jpg" alt="" width="560" height="117" /></p>
<p>I will talk about the new features of Flash Builder 4 that can help you while debugging and I will show how you can use Flash Builder 4 with Eclipse PDT and XDebug. The webinar will be this Wednesday (March 24th), 11AM Central European Time. You can register <a href="http://flexphpdebug-evng.eventbrite.com" target="_blank">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/03/22/debugging-flex-and-php-projects-webinar/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Quick poll on debugging and tooling for Flex and PHP projects</title>
		<link>http://corlan.org/2010/02/25/quick-poll-on-debugging-and-tooling-for-flex-and-php-projects/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=quick-poll-on-debugging-and-tooling-for-flex-and-php-projects</link>
		<comments>http://corlan.org/2010/02/25/quick-poll-on-debugging-and-tooling-for-flex-and-php-projects/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 10:02:54 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1612</guid>
		<description><![CDATA[
			
				
			
		
As you know, one of my focuses as a Platform evangelist is Flex and PHP integration. Thus you can imagine I spend quite a lot of time doing Flex and PHP projects or research around these technologies. Lately I’ve been working on workflows for PHP and Flex (tooling, debugging, libraries) in light of the new [...]]]></description>
			<content:encoded><![CDATA[<div class="none" style="float: right; margin-left: 10px;"><g:plusone href="http://corlan.org/2010/02/25/quick-poll-on-debugging-and-tooling-for-flex-and-php-projects/" size="tall" count="true"></g:plusone></div><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcorlan.org%2F2010%2F02%2F25%2Fquick-poll-on-debugging-and-tooling-for-flex-and-php-projects%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F02%2F25%2Fquick-poll-on-debugging-and-tooling-for-flex-and-php-projects%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>As you know, one of my focuses as a Platform evangelist is Flex and PHP integration. Thus you can imagine I spend quite a lot of time doing Flex and PHP projects or research around these technologies. Lately I’ve been working on workflows for PHP and Flex (tooling, debugging, libraries) in light of the new tools (or new versions) we have been developing at Adobe. While some of these findings will see the light as articles, others are more intended as suggestions or feature request for upcoming versions of Flash Builder.</p>
<p>I’m really curious to find out:</p>
<ul>
<li> What tools are you using?</li>
<li> What do you use for debugging?</li>
<li> What frameworks (AMFPHP, Zend Framework, Doctrine etc) do you use when working on Flex and PHP projects?</li>
<li> And the most important question: What features do you think Flash Builder needs in order to make you a happier/richer developer? </li>
</ul>
<p>Please take some time and drop a comment with your thoughts around these questions.</p>
<p>And because I understand it takes some time to answer these questions, I want to give away<strong> three Flash Builder 4 licenses</strong>. I will choose randomly three lucky people from those who take the survey. The winners will be announced at the end of March, however you’ll get the licenses once we release Flash Builder 4 (now it is in Beta 2). Make sure you fill in your real name and a valid email address.</p>
<p><strong>LATER EDIT:</strong> The winners of this raffle are: Mario Kralj, chandra shekhar pant, and Ben Dalton! Congratulations and pretty soon you&#8217; receive the license.</p>
]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/02/25/quick-poll-on-debugging-and-tooling-for-flex-and-php-projects/feed/</wfw:commentRss>
		<slash:comments>59</slash:comments>
		</item>
		<item>
		<title>Webinar: using PHP and Flash for developing Rich Internet Applications</title>
		<link>http://corlan.org/2009/12/01/webinar-using-php-and-flash-for-developing-rich-internet-applications/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=webinar-using-php-and-flash-for-developing-rich-internet-applications</link>
		<comments>http://corlan.org/2009/12/01/webinar-using-php-and-flash-for-developing-rich-internet-applications/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 11:24:23 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Conferences]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1441</guid>
		<description><![CDATA[
			
				
			
		
On December 2nd, together with Roy Ganor from Zend, I will host an e-seminar about PHP and the Flash Platform. We will show you how you can create a Rich Internet Application using the Flex framework, Illustrator, Flash Catalyst, and Flash Builder 4. Then we will show you how to connect the Flex application to [...]]]></description>
			<content:encoded><![CDATA[<div class="none" style="float: right; margin-left: 10px;"><g:plusone href="http://corlan.org/2009/12/01/webinar-using-php-and-flash-for-developing-rich-internet-applications/" size="tall" count="true"></g:plusone></div><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcorlan.org%2F2009%2F12%2F01%2Fwebinar-using-php-and-flash-for-developing-rich-internet-applications%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2009%2F12%2F01%2Fwebinar-using-php-and-flash-for-developing-rich-internet-applications%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>On December 2nd, together with Roy Ganor from Zend, I will host an e-seminar about PHP and the Flash Platform. We will show you how you can create a Rich Internet Application using the Flex framework, Illustrator, Flash Catalyst, and Flash Builder 4. Then we will show you how to connect the Flex application to a PHP backend and how easy is to debug the PHP and Flex code using Zend Studio 7.1 and Flash Builder 4.</p>
<p>You can register for free <a href="https://zend.webex.com/zend/onstage/g.php?d=570538538" target="_self">here</a>. The webinar will start at 6:00 PM Central European Time (9:00AM Pacific Standard Time) on December 2nd.</p>
<p>LATER UPDATE:</p>
<p>You can download the slides from <a href="http://corlan.org/downloads/PHP_Flex_Webinar.pdf">here</a>, and <span style="text-decoration: line-through;">next week the recording will be available</span> you can watch the recording over <a href="http://www.zend.com/webinar/Studio/webinar-using-php-and-flash-for-developing-rich-internet-applications-20091202.flv" target="_blank">here</a> (you need to have a Zend account).</p>
]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2009/12/01/webinar-using-php-and-flash-for-developing-rich-internet-applications/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>PHP and Flex Webinars</title>
		<link>http://corlan.org/2009/11/09/php-and-flex-webinars/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=php-and-flex-webinars</link>
		<comments>http://corlan.org/2009/11/09/php-and-flex-webinars/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 18:46:01 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Conferences]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1367</guid>
		<description><![CDATA[
			
				
			
		
Last week I visited Zend headquarters, and I had an interesting talk over there. One effect of this meeting is this: we will start to do webinars together with Zend.
If you want to find more about Zend Studio and other products related to PHP from Zend, or learn more about the integration between the Flash [...]]]></description>
			<content:encoded><![CDATA[<div class="none" style="float: right; margin-left: 10px;"><g:plusone href="http://corlan.org/2009/11/09/php-and-flex-webinars/" size="tall" count="true"></g:plusone></div><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcorlan.org%2F2009%2F11%2F09%2Fphp-and-flex-webinars%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2009%2F11%2F09%2Fphp-and-flex-webinars%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Last week I visited Zend headquarters, and I had an interesting talk over there. One effect of this meeting is this: we will start to do webinars together with Zend.</p>
<p>If you want to find more about Zend Studio and other products related to PHP from Zend, or learn more about the integration between the Flash Platform and PHP (Flash Catalyst, Flash Builder, Flex framework) you shouldn&#8217;t miss this opportunity. I know that webinars don&#8217;t offer the same experience as in-person events. On the other hand, you can attend them from the comfort of your own home, there is no traveling involved and no need to convince your boss to let you attend the event.</p>
<div><img class="alignnone size-full wp-image-1369" title="a2" src="http://corlan.org/wp-content/uploads/2009/11/a2.png" alt="a2" width="257" height="120" /><img class="alignnone size-full wp-image-1368" title="a1" src="http://corlan.org/wp-content/uploads/2009/11/a1.png" alt="a1" width="257" height="120" /></div>
<p>We haven&#8217;t set the first event date yet, but it should be in the first week of December, and probably it will be in the evening (Central European Time).</p>
<p>Keep an eye on my blog for the exact date and time.</p>
]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2009/11/09/php-and-flex-webinars/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Flex for PHP developers article</title>
		<link>http://corlan.org/2009/08/14/flex-for-php-developers-article/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=flex-for-php-developers-article</link>
		<comments>http://corlan.org/2009/08/14/flex-for-php-developers-article/#comments</comments>
		<pubDate>Fri, 14 Aug 2009 12:18:57 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://corlan.org/2009/08/14/flex-for-php-developers-article/</guid>
		<description><![CDATA[
			
				
			
		
Finally, I managed to finish an article that introduces Flex to PHP developers comparing features from both worlds (when it makes sense). I’ve been working on this subject from the beginning of this year. Thus I am so happy that I feel I should go out and smoke a fine Cuban cigar :)
While working on [...]]]></description>
			<content:encoded><![CDATA[<div class="none" style="float: right; margin-left: 10px;"><g:plusone href="http://corlan.org/2009/08/14/flex-for-php-developers-article/" size="tall" count="true"></g:plusone></div><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcorlan.org%2F2009%2F08%2F14%2Fflex-for-php-developers-article%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2009%2F08%2F14%2Fflex-for-php-developers-article%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Finally, I managed to finish an article that introduces <a href="http://corlan.org/flex-for-php-developers/" target="_blank">Flex to PHP developers</a> comparing features from both worlds (when it makes sense). I’ve been working on this subject from the beginning of this year. Thus I am so happy that I feel I should go out and smoke a fine Cuban cigar :)</p>
<p>While working on this article I realized two things:</p>
<ol>
<li>Writing books it is not easy. My work doesn’t compare with a book at all, but still the amount of work was huge. Now, I have an idea about what it means to work on a book.</li>
<li>Learning a client-side technology coming from the server-side world will never be an easy and straightforward task. You have to adapt to a new world and adopt a different mindset. But then again, with big efforts usually come big rewards! And from my experience, when I learn something new I can always apply some of this knowledge to the concepts I’ve already known.</li>
</ol>
<p>Enjoy the article and let me know what do you think!</p>
]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2009/08/14/flex-for-php-developers-article/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Working in Flash Builder 4 with Flex and PHP</title>
		<link>http://corlan.org/2009/06/12/working-in-flash-builder-4-with-flex-and-php/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=working-in-flash-builder-4-with-flex-and-php</link>
		<comments>http://corlan.org/2009/06/12/working-in-flash-builder-4-with-flex-and-php/#comments</comments>
		<pubDate>Fri, 12 Jun 2009 12:45:53 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://corlan.org/2009/06/12/working-in-flash-builder-4-with-flex-and-php/</guid>
		<description><![CDATA[
			
				
			
		
On June 1st we launched the public beta for Flash Builder 4, the newest iteration of our Eclipse-based IDE for RIAs, formerly known as Flex Builder 3. While you can find both evolutionary and revolutionary features in it, in this article I will touch on the data features and Flex – PHP integration features of [...]]]></description>
			<content:encoded><![CDATA[<div class="none" style="float: right; margin-left: 10px;"><g:plusone href="http://corlan.org/2009/06/12/working-in-flash-builder-4-with-flex-and-php/" size="tall" count="true"></g:plusone></div><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcorlan.org%2F2009%2F06%2F12%2Fworking-in-flash-builder-4-with-flex-and-php%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2009%2F06%2F12%2Fworking-in-flash-builder-4-with-flex-and-php%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>On June 1st we launched the public beta for Flash Builder 4, the newest iteration of our Eclipse-based IDE for RIAs, formerly known as Flex Builder 3. While you can find both evolutionary and revolutionary features in it, in this article I will touch on the data features and Flex – PHP integration features of Flash Builder 4.</p>
<p>In this article, I will show you how can you use a PHP class that manages a MySQL table (offering CRUD operations) in a Flex project. I will build the Flex project and I rely on Flash Builder 4 to set up the Zend Framework for me(because I want to use remoting as a way to talk with the PHP server). After this I will use the new wizard from Flash Builder 4 that introspects a PHP class and creates the ActionScript code to consume that PHP class.</p>
<p>In the end I should be able to have a simple Flex app that lets me see the data records, edit them, and add a new item. For some of the features I’ll have to write code, for others Flash Builder will generate the code. All in all, I think the application can be created in less than 30 minutes.</p>
<h2>PHP code</h2>
<p>I have two PHP classes that I want to reuse with my Flex application. One class is a data object that acts asa wrapper for one row from my database (MySQL). Here is the structure of the table:</p>
<p>authors    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;     <br />id_aut – primary key     <br />fname_aut string     <br />lname_aut string</p>
<p>The PHP data object, called <em>VOAuthor</em>, looks like this:</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4; max-height: 200px">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">class</span> VOAuthor {</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span>    </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>     <span style="color: #0000ff">public</span> $id_aut;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>     <span style="color: #0000ff">public</span> $fname_aut;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>     <span style="color: #0000ff">public</span> $lname_aut;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span> }</pre>
</p></div>
</div>
<p>&#160;</p>
<p>The second class, called <em>Authors</em>, is the class that manages the table, offering CRUD operations. The code is very straight forward, I don’t use any database abstraction layer. I have three methods one each for reading, deleting, and updating/inserting a record. I use the data object, <em>VOAuthor</em>, within these methods. This is the code:</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; height: 259px; background-color: #f4f4f4; max-height: 200px">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> require_once <span style="color: #006080">'VOAuthor.php'</span>;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span>&#160; </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>&#160; </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span> <span style="color: #008000">//connection info</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span> define(<span style="color: #006080">&quot;DATABASE_SERVER&quot;</span>, <span style="color: #006080">&quot;localhost&quot;</span>);</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span> define(<span style="color: #006080">&quot;DATABASE_USERNAME&quot;</span>, <span style="color: #006080">&quot;mihai&quot;</span>);</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span> define(<span style="color: #006080">&quot;DATABASE_PASSWORD&quot;</span>, <span style="color: #006080">&quot;mihai&quot;</span>);</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span> define(<span style="color: #006080">&quot;DATABASE_NAME&quot;</span>, <span style="color: #006080">&quot;flex360&quot;</span>);</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   9:</span>&#160; </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span> <span style="color: #008000">//$o = new MyService();</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  11:</span> <span style="color: #008000">//print_r($o-&gt;getData());</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  12:</span>&#160; </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  13:</span> <span style="color: #0000ff">class</span> Authors {</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  14:</span>     </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  15:</span>     <span style="color: #008000">/**</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  16:</span> <span style="color: #008000">     * Retrieve all the records from the table</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  17:</span> <span style="color: #008000">     * @return an array of VOAuthor</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  18:</span> <span style="color: #008000">     */</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  19:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">function</span> getData() {</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  20:</span>         <span style="color: #008000">//connect to the database.</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  21:</span>         <span style="color: #008000">//we could have used an abstracting layer for connecting to the database.</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  22:</span>         <span style="color: #008000">//for the sake of simplicity, I choose not to.</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  23:</span>         $mysql = mysql_connect(DATABASE_SERVER, DATABASE_USERNAME, DATABASE_PASSWORD);</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  24:</span>         mysql_select_db(DATABASE_NAME);</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  25:</span>         <span style="color: #008000">//retrieve all rows</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  26:</span>         $query = <span style="color: #006080">&quot;SELECT id_aut, fname_aut, lname_aut FROM authors_aut ORDER BY fname_aut&quot;</span>;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  27:</span>         $result = mysql_query($query);</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  28:</span>         <span style="color: #008000">//throw (new Zend_Amf_Exception('error', 11));</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  29:</span>         $ret = array();</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  30:</span>         <span style="color: #0000ff">while</span> ($row = mysql_fetch_object($result, <span style="color: #006080">&quot;VOAuthor&quot;</span>)) {</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  31:</span>             $ret[] = $row;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  32:</span>         }</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  33:</span>         mysql_free_result($result); </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  34:</span>         <span style="color: #0000ff">return</span> $ret;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  35:</span>     }</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  36:</span>         <span style="color: #008000">/**</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  37:</span> <span style="color: #008000">     * Update one item in the table</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  38:</span> <span style="color: #008000">     * @param VOAuthor to be updated </span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  39:</span> <span style="color: #008000">     * @return NULL</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  40:</span> <span style="color: #008000">     */</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  41:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">function</span> saveData($author) {</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  42:</span>         <span style="color: #0000ff">if</span> ($author == NULL)</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  43:</span>             <span style="color: #0000ff">return</span> NULL;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  44:</span>         <span style="color: #008000">//logMe($author);</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  45:</span>         <span style="color: #008000">//connect to the database.</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  46:</span>         $mysql = mysql_connect(DATABASE_SERVER, DATABASE_USERNAME, DATABASE_PASSWORD);</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  47:</span>         mysql_select_db(DATABASE_NAME);</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  48:</span>         <span style="color: #0000ff">if</span> ($author-&gt;id_aut &gt; 0) {</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  49:</span>             <span style="color: #008000">//save changes</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  50:</span>             $query = <span style="color: #006080">&quot;UPDATE authors_aut SET fname_aut='&quot;</span>.$author-&gt;fname_aut.<span style="color: #006080">&quot;', lname_aut='&quot;</span>.$author-&gt;lname_aut.<span style="color: #006080">&quot;' WHERE id_aut=&quot;</span>.  $author-&gt;id_aut;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  51:</span>         } <span style="color: #0000ff">else</span> {</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  52:</span>             <span style="color: #008000">//add new record</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  53:</span>             $query = <span style="color: #006080">&quot;INSERT INTO authors_aut (fname_aut, lname_aut) VALUES ('&quot;</span>.$author-&gt;fname_aut.<span style="color: #006080">&quot;', '&quot;</span>.$author-&gt;lname_aut.<span style="color: #006080">&quot;')&quot;</span>;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  54:</span>         }</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  55:</span>         $result = mysql_query($query);</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  56:</span>         <span style="color: #0000ff">return</span> NULL;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  57:</span>     }</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  58:</span>     </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  59:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">function</span> deleteData($author) {</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  60:</span>         <span style="color: #0000ff">if</span> ($author == NULL)</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  61:</span>             <span style="color: #0000ff">return</span> NULL;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  62:</span>         </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  63:</span>         <span style="color: #008000">//connect to the database.</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  64:</span>         $mysql = mysql_connect(DATABASE_SERVER, DATABASE_USERNAME, DATABASE_PASSWORD);</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  65:</span>         mysql_select_db(DATABASE_NAME);</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  66:</span>         <span style="color: #008000">//add new record</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  67:</span>         $query = <span style="color: #006080">&quot;DELETE FROM authors_aut WHERE id_aut = &quot;</span>.$author-&gt;id_aut;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  68:</span>         $result = mysql_query($query);</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  69:</span>         <span style="color: #0000ff">return</span> NULL;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  70:</span>     }</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  71:</span>     </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  72:</span> }</pre>
</p></div>
</div>
<p>These two scripts sit inside of a folder called “remoting” in the root of the Apache web server document root folder.</p>
<h2>Creating the Flex project and the UI of the app</h2>
<p>I have the PHP files in place; now it’s time to create the Flex application. First, I need to create a new Flex project. Having opened the Flash Builder 4, I use the “New Flex Project” wizard to create a new Flex project called <em>FlexPHPAMF</em>. Make sure that in the wizard you choose PHP as the server technology, and you give the correct information for the document root of the web server (absolute path and URL).</p>
<p>Now let’s create the UI of the application. To do this, I chose to go in design mode where I added two buttons and a data grid to the stage. One button is labeled “Get Data” and the other one “Save Data”.</p>
<p><a href="http://corlan.org/wp-content/uploads/2009/06/fb_0.png"><img title="fb_0" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="482" alt="fb_0" src="http://corlan.org/wp-content/uploads/2009/06/fb_0_thumb.png" width="591" border="0" /></a></p>
<h2>Using the data service panel</h2>
<p>Finally, I am ready to use the new data wizards.At the bottom of Flash Builder, there is a view called “Data/Services”. Click on “Connect to Data/Service” link. A wizard starts, and you can select the type of the data service.</p>
<p><a href="http://corlan.org/wp-content/uploads/2009/06/fb_php_1.png"><img title="fb_php_1" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="482" alt="fb_php_1" src="http://corlan.org/wp-content/uploads/2009/06/fb_php_1_thumb.png" width="366" border="0" /></a></p>
<p>Because I want to use the PHP classes I have, I choose PHP and I click “Next”.</p>
<p><a href="http://corlan.org/wp-content/uploads/2009/06/fb_php_2.png"><img title="fb_php_2" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="482" alt="fb_php_2" src="http://corlan.org/wp-content/uploads/2009/06/fb_php_2_thumb.png" width="410" border="0" /></a>&#160;</p>
<p>On this page, you can select to either reuse an existing service from the server, or to let the wizard create a stub for you. Because I have the service, I want to use the Import PHP class option. Flash Builder introspects the service in order to detect the supported operations (in this case, because I am using remoting, it detects the public methods and the return type). But to do so, it needs to install the Zend Framework to your web server.</p>
<p>What is very cool is that you don’t have to worry about the steps needed to install Zend Framework. Flash Builder will do it for you automatically.</p>
<p><a href="http://corlan.org/wp-content/uploads/2009/06/fb_php_3.png"><img title="fb_php_3" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="482" alt="fb_php_3" src="http://corlan.org/wp-content/uploads/2009/06/fb_php_3_thumb.png" width="487" border="0" /></a></p>
<p>After the Zend Framework is installed, on the last page of the wizard you’ll see the available methods. Click Finish.</p>
<p><a href="http://corlan.org/wp-content/uploads/2009/06/fb_php_4.png"><img title="fb_php_4" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="482" alt="fb_php_4" src="http://corlan.org/wp-content/uploads/2009/06/fb_php_4_thumb.png" width="411" border="0" /></a></p>
<p>Now, in the Data/Services view you should have a tree, with the root node named Authors. This is the name of the PHP class that you want to use in Flex. Under this node you have Data Types, and the three methods: deleteData(), getData(), saveData().</p>
<p><a href="http://corlan.org/wp-content/uploads/2009/06/fb_php_5.png"><img title="fb_php_5" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="203" alt="fb_php_5" src="http://corlan.org/wp-content/uploads/2009/06/fb_php_5_thumb.png" width="642" border="0" /></a>&#160;</p>
<p>At the same time if you take a look at the project structure in the Package explorer, you’ll notice that new packages and files were created.</p>
<p><a href="http://corlan.org/wp-content/uploads/2009/06/fb_php_6.png"><img title="fb_php_6" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="482" alt="fb_php_6" src="http://corlan.org/wp-content/uploads/2009/06/fb_php_6_thumb.png" width="309" border="0" /></a></p>
<p>There is a new package called services.authors, and here you’ll find the service class that you’ll use to connect to the PHP class (Authors.as). This class actually extends a base class that implements all the logic using RemoteObject. The reason for this approach is that when you need to do your customization, you’ll do it in the Authors class. If you decide to use Flash Builder to regenerate the code for the same service (maybe as a result of a change on the server side), this operation will not over write your custom code.</p>
<p>The same goes for the data object (or value object). Flash Builder generated the ActionScript value object to match the PHP class VOAuthor. But again, you might want to do some customizations, and you can do it by touching VOAuthor that extends _Super_VOAuthor. All the generated code stays in the _Super_VOAuthor.</p>
<p>And finally, you’ll find a folder called <em>services</em> that gives you quick access to the Authors.php class.</p>
<p>It is time to fill the data grid with the data from the server. To do so, first you need to make sure that the return type for the getData() operation is an array of VOAuthor objects. If you right click on the name of the operation in the Data/Services view and choose Configure Return Type, you have a way to specify the array of VOAuthor:</p>
<p><a href="http://corlan.org/wp-content/uploads/2009/06/fb_php_7.png"><img title="fb_php_7" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="482" alt="fb_php_7" src="http://corlan.org/wp-content/uploads/2009/06/fb_php_7_thumb.png" width="582" border="0" /></a></p>
<p>To bind the data grid to the result of the getData() operation you have to go into design mode, and then drag and drop the getData() (from the Data/Services view) to the data grid.</p>
<p>If you switch to code view, you’ll see that some ActionScript code was added to the flexPHPAMF.mxml. What you want to do is to grab the line from the function and create a new function that will be called when you click the “Get Data” button and paste the code inside of it. My code looks like this:</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4; max-height: 200px">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">protected</span> <span style="color: #0000ff">function</span> getData():<span style="color: #0000ff">void</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> {</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>    getDataResult.token = authors.getData();</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span> }</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span> [...]</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>&#160; </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span> &lt;s:Button x=<span style="color: #006080">&quot;43&quot;</span> y=<span style="color: #006080">&quot;220&quot;</span> label=<span style="color: #006080">&quot;Get Data&quot;</span> click=<span style="color: #006080">&quot;getData()&quot;</span>/&gt;</pre>
</p></div>
</div>
<p>The wizard altered the data grid itself, you have the name of the table fields as labels, and the data provider of the data grid is set to the lastResult of the getDataResult object (this object was added to your code by the wizard, in order to help you manage the results of the authors service).</p>
<p>If you run the application and press the “Get Data” button, you should see the data.</p>
<h2>Adding editing capabilities</h2>
<p>The final part of this tutorial is adding the editing capabilities. I want to be able to edit an existing record using the data grid itself, and I want to have a form and a new button. First go back into design mode, drag and drop an new button on the stage, and change the label to “New”. Then, you’ll use another wizard to generate the form for editing. To do so, you select from the Data/Services view the Data Types node, expand it, and select the VOAuthor node. Right click it and select Generate Form. In the wizard choose “Make form editable” and click Next.</p>
<p><a href="http://corlan.org/wp-content/uploads/2009/06/fb_php_8.png"><img title="fb_php_8" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="482" alt="fb_php_8" src="http://corlan.org/wp-content/uploads/2009/06/fb_php_8_thumb.png" width="484" border="0" /></a></p>
<p>In the second page of the wizard deselect the “id_aut” property. This value will be auto-inserted by the database itself. Click Finish.</p>
<p><a href="http://corlan.org/wp-content/uploads/2009/06/fb_php_9.png"><img title="fb_php_9" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="482" alt="fb_php_9" src="http://corlan.org/wp-content/uploads/2009/06/fb_php_9_thumb.png" width="486" border="0" /></a></p>
<p>After the form is generated, you want to grab the form and position it maybe below the buttons. Also, you may want to change the labels. Finally add a new button in the form and label it “Add”.</p>
<p>Switch back to code view. Now, you need to make some changes. First of all (I think it is a bug), the text fields are not editable (they are Text instead of TextInput). So change the type to TextInput to make them editable. Next, give an ID to the Form itself. I want to have the form invisible when the application is loaded, and only make it visible when the users clicks “New”. For that you set the visible property on the form to false, and you add some code to the New button. Here is my code:</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4; max-height: 200px">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> &lt;s:Button x=<span style="color: #006080">&quot;224&quot;</span> y=<span style="color: #006080">&quot;220&quot;</span> label=<span style="color: #006080">&quot;New&quot;</span> click=<span style="color: #006080">&quot;myForm.visible = true&quot;</span>/&gt;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> &lt;mx:Form x=<span style="color: #006080">&quot;46&quot;</span> y=<span style="color: #006080">&quot;277&quot;</span> id=<span style="color: #006080">&quot;myForm&quot;</span> visible=<span style="color: #006080">&quot;false&quot;</span>&gt;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>         &lt;mx:FormItem label=<span style="color: #006080">&quot;First Name:&quot;</span>&gt;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>             &lt;mx:TextInput id=<span style="color: #006080">&quot;fname&quot;</span> text=<span style="color: #006080">&quot;&quot;</span>/&gt;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>         &lt;/mx:FormItem&gt;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>         &lt;mx:FormItem label=<span style="color: #006080">&quot;Last Name:&quot;</span>&gt;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span>             &lt;mx:TextInput id=<span style="color: #006080">&quot;lname&quot;</span> text=<span style="color: #006080">&quot;&quot;</span>/&gt;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>         &lt;/mx:FormItem&gt;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   9:</span>         &lt;mx:FormItem&gt;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span>             &lt;s:Button label=<span style="color: #006080">&quot;Add&quot;</span>/&gt;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  11:</span>         &lt;/mx:FormItem&gt;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  12:</span> &lt;/mx:Form&gt;</pre>
</p></div>
</div>
<p>And if you look in the code, you’ll notice a new object was created:</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4; max-height: 200px">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> &lt;authors:VOAuthor id=<span style="color: #006080">&quot;vOAuthor&quot;</span>/&gt;</pre>
</p></div>
</div>
<p>You’ll use this instance of the value object VOAuthor to send the new item to the server (remember, the PHP saveData() method expects a single argument of type VOAuthor).</p>
<p>To do so, you need to create a binding between the two text fields from the form and the properties fname_aut and lname_aut of the VOAuthor.</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4; max-height: 200px">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> &lt;fx:Binding destination=<span style="color: #006080">&quot;vOAuthor.fname_aut&quot;</span> source=<span style="color: #006080">&quot;fname.text&quot;</span>/&gt;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> &lt;fx:Binding destination=<span style="color: #006080">&quot;vOAuthor.lname_aut&quot;</span> source=<span style="color: #006080">&quot;lname.text&quot;</span>/&gt;</pre>
</p></div>
</div>
<p>The last missing piece is the actual call to the saveData() method. This is very simple;on the click event of the “Save” button you add the call to the authors object getData() method, passing the local instance of VOAuthor (vOAuthor) as the argument:</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; height: 35px; background-color: #f4f4f4; max-height: 200px">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> &lt;s:Button label=<span style="color: #006080">&quot;Add&quot;</span> click=<span style="color: #006080">&quot;authors.saveData(vOAuthor)&quot;</span>/&gt;</pre>
</p></div>
</div>
<p>You can add a new record now. What about editing an existing one? For this we will need a little bit more code. First, you want to register a listener on the data grid in order to know when something was edited (if you set the property editable to true on the data grid, then you can edit information inline). The event you are looking for is itemEditEnd:</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4; max-height: 200px">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> &lt;mx:DataGrid x=<span style="color: #006080">&quot;44&quot;</span> y=<span style="color: #006080">&quot;37&quot;</span> id=<span style="color: #006080">&quot;dataGrid&quot;</span> dataProvider=<span style="color: #006080">&quot;{getDataResult.lastResult}&quot;</span> </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span>         itemEditEnd=<span style="color: #006080">&quot;dataEdited(event)&quot;</span> editable=<span style="color: #006080">&quot;true&quot;</span>&gt;</pre>
</p></div>
</div>
<p>Now,let’s define the listener, dataEdited(). Add the following code in the script section of the page:</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4; max-height: 200px">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">private</span> <span style="color: #0000ff">function</span> dataEdited(<span style="color: #0000ff">event</span>: DataGridEvent):<span style="color: #0000ff">void</span> </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> {</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>      vOAuthor = <span style="color: #0000ff">event</span>.itemRenderer.data <span style="color: #0000ff">as</span> VOAuthor;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span> }</pre>
</p></div>
</div>
<p>This code uses the instance of the value object VOAuthor to store the data used by the edited row.</p>
<p>The last two things you have to do is to create a function called saveData() that is called when the user clicks the “Save Data” button, and to add initialization code for the vOAuthor object when the users clicks the “New” button (this way you avoid updating an item instead of adding a new one if you first edit a row and then add one):</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4; max-height: 200px">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">private</span> <span style="color: #0000ff">function</span> saveData():<span style="color: #0000ff">void</span> {</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span>    <span style="color: #0000ff">if</span> (vOAuthor != <span style="color: #0000ff">null</span>)</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>       authors.saveData(vOAuthor);</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span> }</pre>
</p></div>
</div>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4; max-height: 200px">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> &lt;s:Button x=<span style="color: #006080">&quot;224&quot;</span> y=<span style="color: #006080">&quot;220&quot;</span> label=<span style="color: #006080">&quot;New&quot;</span> </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span>     click=<span style="color: #006080">&quot;myForm.visible = true; vOAuthor = new VOAuthor()&quot;</span>/&gt;</pre>
</p></div>
</div>
<p>The final code of the MXML file should look like this:</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; height: 360px; background-color: #f4f4f4; max-height: 200px">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> &lt;?xml version=<span style="color: #006080">&quot;1.0&quot;</span> encoding=<span style="color: #006080">&quot;utf-8&quot;</span>?&gt;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> &lt;s:Application xmlns:fx=<span style="color: #006080">&quot;http://ns.adobe.com/mxml/2009&quot;</span> xmlns:s=<span style="color: #006080">&quot;library://ns.adobe.com/flex/spark&quot;</span> xmlns:mx=<span style="color: #006080">&quot;library://ns.adobe.com/flex/halo&quot;</span> minWidth=<span style="color: #006080">&quot;1024&quot;</span> minHeight=<span style="color: #006080">&quot;768&quot;</span> xmlns:authors=<span style="color: #006080">&quot;services.authors.*&quot;</span>&gt;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>     &lt;fx:Script&gt;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>         &lt;![CDATA[</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>             import mx.events.DataGridEvent;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>             import services.authors.VOAuthor;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span>             import mx.events.FlexEvent;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>             import mx.controls.Alert;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   9:</span>             </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span>             <span style="color: #0000ff">protected</span> <span style="color: #0000ff">function</span> getData():<span style="color: #0000ff">void</span></pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  11:</span>             {</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  12:</span>                 getDataResult.token = authors.getData();</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  13:</span>             }</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  14:</span>             </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  15:</span>             <span style="color: #0000ff">private</span> <span style="color: #0000ff">function</span> dataEdited(<span style="color: #0000ff">event</span>: DataGridEvent):<span style="color: #0000ff">void</span> </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  16:</span>             {</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  17:</span>                 vOAuthor = <span style="color: #0000ff">event</span>.itemRenderer.data <span style="color: #0000ff">as</span> VOAuthor;</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  18:</span>             }</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  19:</span>             </pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  20:</span>             <span style="color: #0000ff">private</span> <span style="color: #0000ff">function</span> saveData():<span style="color: #0000ff">void</span> {</pre>
<p>
      </p>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; col
