<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Mihai Corlan</title>
	
	<link>http://corlan.org</link>
	<description>Flex, AIR and Rock&amp;Roll</description>
	<lastBuildDate>Mon, 30 Aug 2010 04:21:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/corlan" /><feedburner:info uri="corlan" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>About AIR Applications and Android Permissions</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/kSBQIDDRfdI/</link>
		<comments>http://corlan.org/2010/08/30/about-air-android-permissions/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 04:00:29 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2167</guid>
		<description><![CDATA[




			
				
			
		
After I saw some tweets about issues related to accessing the Wi-Fi network from an AIR application running on Android I thought it is worth writing a post about this topic.
If you installed an Android application on your phone you know that during this process you are presented with a screen stating what permissions the [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/08/30/about-air-android-permissions/&title=About AIR Applications and Android Permissions&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F30%2Fabout-air-android-permissions%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F08%2F30%2Fabout-air-android-permissions%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>After I saw some tweets about issues related to accessing the Wi-Fi network from an AIR application running on Android I thought it is worth writing a post about this topic.</p>
<p>If you installed an Android application on your phone you know that during this process you are presented with a screen stating what permissions the application you are about to install will use: network communication, contact data, location, storage, and so on.</p>
<p>I think this is a good thing especially when dealing with applications from &#8220;not so trusted&#8221; sources. You have a last chance to decide if you are willing to install that app or not. Thus it is only natural Android apps build with Adobe AIR to follow the same rules. One more thing on security/permissions: I think it is a best practice, as a developer, to request the minimum permissions required for your application.</p>
<p>The way you setup these permissions is quite simple: you add an &lt;android&gt; node to your application descriptor file having the root the &lt;application&gt; node (the application descriptor file is the XML file you already use for setting the different configuration options for your AIR application &#8211; application name, enabling the update framework, initial size and position, and so on). Here is an example:</p>
<pre>&lt;android&gt;
    &lt;manifestAdditions&gt;
        &lt;manifest&gt;
            &lt;attribute name="android:installLocation" value="auto"/&gt;
            &lt;data&gt;
            &lt;![CDATA[
                &lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/&gt;
                &lt;uses-permission android:name="android.permission.INTERNET"/&gt;
                &lt;uses-permission android:name="android.permission.WAKE_LOCK"/&gt;
                &lt;uses-permission android:name="android.permission.DISABLE_KEYGUARD"/&gt;
                &lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/&gt;
                &lt;uses-permission android:name="android.permission.READ_PHONE_STATE"/&gt;
            ]]&gt;
            &lt;/data&gt;
        &lt;/manifest&gt;
    &lt;/manifestAdditions&gt;
&lt;/android&gt;
</pre>
<p>In this example I added an additional setting in the form of &lt;attribute name=&#8221;android:installLocation&#8221; value=&#8221;atuot&#8221;/&gt; in order to allow the user to install the application either on the internal memory or on the SD memory card. The same way you can add additional permissions supported by the Android OS.</p>
<p>Now, next time when you have problems accessing resources from your AIR app on Android, you should know what is the first thing to look for.</p>
<div class="shr-publisher-2167"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/08/30/about-air-android-permissions/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/kSBQIDDRfdI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/08/30/about-air-android-permissions/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/08/30/about-air-android-permissions/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=about-air-android-permissions</feedburner:origLink></item>
		<item>
		<title>Hero is available</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/fnoWsS4sLRc/</link>
		<comments>http://corlan.org/2010/08/27/hero-is-available/#comments</comments>
		<pubDate>Fri, 27 Aug 2010 14:58:25 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2165</guid>
		<description><![CDATA[




			
				
			
		
The next version of the Flex SDK, codename Hero, is available to you for download now. If you want to check this special builds just go here and download.
What is so special about Hero? Well, the most important thing is the added support for mobile development. So far you&#8217;ll find in this builds: Spark DataGrid, [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/08/27/hero-is-available/&title=Hero is available&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F27%2Fhero-is-available%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F08%2F27%2Fhero-is-available%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>The next version of the Flex SDK, codename Hero, is available to you for download now. If you want to check this special builds just go here and <a href="http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+Hero" target="_blank">download</a>.</p>
<p>What is so special about Hero? Well, the most important thing is the added support for mobile development. So far you&#8217;ll find in this builds: Spark DataGrid, Spark Image, Spark Form, OSMF 1.0 integration, Mobile Application, View &amp; View Navigator, and ActionBar. You can read more <a href="http://opensource.adobe.com/wiki/display/flexsdk/Hero" target="_blank">here</a>.</p>
<p>No go and start play with it already :D!</p>
<div class="shr-publisher-2165"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/08/27/hero-is-available/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/fnoWsS4sLRc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/08/27/hero-is-available/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/08/27/hero-is-available/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=hero-is-available</feedburner:origLink></item>
		<item>
		<title>Application Updater Library for AIR Native Installer Apps</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/OspCvCbeGRQ/</link>
		<comments>http://corlan.org/2010/08/25/application-updater-library-for-air-native-installer-apps/#comments</comments>
		<pubDate>Wed, 25 Aug 2010 11:47:32 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[AIR]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2161</guid>
		<description><![CDATA[




			
				
			
		
My fellow evangelist, Piotr Walczyszyn, was very busy this summer tinkering with a number of projects that involve Adobe AIR. The latest one is library that enables you to update native AIR applications. You probably know that AIR 2 introduced a cool feature that lets you call processes from your AIR application (Native Processes API) [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/08/25/application-updater-library-for-air-native-installer-apps/&title=Application Updater Library for AIR Native Installer Apps&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F25%2Fapplication-updater-library-for-air-native-installer-apps%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F08%2F25%2Fapplication-updater-library-for-air-native-installer-apps%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>My fellow evangelist, Piotr Walczyszyn, was very busy this summer tinkering with a number of projects that involve Adobe AIR. The latest one is library that enables you to update native AIR applications. You probably know that AIR 2 introduced a cool feature that lets you call processes from your AIR application (Native Processes API) as long as you package your application as a native installer (EXE, DMG, RPM etc). Once you do this, the built-in feature for update doesn&#8217;t work anymore.</p>
<p>If you want to have update capabilities with AIR 2 native installers you can use Piotr&#8217;s library or you can build your own mechanism. The choice is pretty simple, isn&#8217;t it?</p>
<p>Here is a video in which Piotr demos the library:</p>
<p><iframe src="http://player.vimeo.com/video/14400178?portrait=0" frameborder="0" height="338" width="600"></iframe></p>
<p>You can get the library from <a href="http://code.google.com/p/nativeapplicationupdater/" target="_blank">here</a> or read Piotr&#8217;s <a href="http://www.riaspace.com/2010/08/nativeapplicationupdater-updater-for-air-apps-packaged-with-native-installers/" target="_blank">post</a>.</p>
<div class="shr-publisher-2161"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/08/25/application-updater-library-for-air-native-installer-apps/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/OspCvCbeGRQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/08/25/application-updater-library-for-air-native-installer-apps/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/08/25/application-updater-library-for-air-native-installer-apps/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=application-updater-library-for-air-native-installer-apps</feedburner:origLink></item>
		<item>
		<title>Adobe AIR Launchpad helps you creating AIR apps/projects</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/wjsjD0egmVM/</link>
		<comments>http://corlan.org/2010/08/23/adobe-air-launchpad-helps-you-creating-air-appsprojects/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 17:58:24 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Flash Builder]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2145</guid>
		<description><![CDATA[




			
				
			
		
We&#8217;ve just launched Adobe AIR Launchpad: an AIR application that can speed up your AIR development.

How does AIR Launchpad help you? Here is a list of some of the features:

It creates the folder structure for an AIR application ready to compile with the settings you want it. For example, if you want to use auto [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/08/23/adobe-air-launchpad-helps-you-creating-air-appsprojects/&title=Adobe AIR Launchpad helps you creating AIR apps/projects&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F23%2Fadobe-air-launchpad-helps-you-creating-air-appsprojects%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F08%2F23%2Fadobe-air-launchpad-helps-you-creating-air-appsprojects%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>We&#8217;ve just launched Adobe AIR Launchpad: an AIR application that can speed up your AIR development.</p>
<p><img class="aligncenter size-full wp-image-2147" title="launchpad" src="http://corlan.org/wp-content/uploads/2010/08/launchpad.jpg" alt="" width="250" height="207" /></p>
<p>How does AIR Launchpad help you? Here is a list of some of the features:</p>
<ul>
<li>It creates the folder structure for an AIR application ready to compile with the settings you want it. For example, if you want to use auto update feature, then it will create the server side folder and files needed for this feature to work. If you&#8217;ve done AIR development you know that most the configuration options you need to set are stored inside of an XML file. Well, this application provides a user interface for setting these options. So it makes it easier to set up the icons used by the app, default width/height, or making the app transparent.</li>
<li>It creates an install badge if you need one (you can provide the image you want to be used).</li>
<li>It helps you to hook up listeners for events like Activation/Deactivation, Close event, Global Error.</li>
<li>It generates sample code for tasks like: Drag/Drop, Local Databases, Using Windows, HTML Component, Native Process, and many more.</li>
<li>It can create a ZIP file with all these folders/files so you can import this ZIP in Flash Builder and continue the working on the application using this IDE.</li>
</ul>
<p>Here are some screenshots:</p>
<p style="text-align: center;"><img class="aligncenter size-medium wp-image-2150" title="l1" src="http://corlan.org/wp-content/uploads/2010/08/l11-300x191.png" alt="" width="300" height="191" /><img class="aligncenter size-medium wp-image-2151" title="l2" src="http://corlan.org/wp-content/uploads/2010/08/l2-300x191.png" alt="" width="300" height="191" /><img class="aligncenter size-medium wp-image-2152" title="l3" src="http://corlan.org/wp-content/uploads/2010/08/l3-300x191.png" alt="" width="300" height="191" /><img class="aligncenter size-medium wp-image-2153" title="l4" src="http://corlan.org/wp-content/uploads/2010/08/l4-300x191.png" alt="" width="300" height="191" /></p>
<p>You can get this application from <a href="http://labs.adobe.com/technologies/airlaunchpad/" target="_blank">here</a>.</p>
<div class="shr-publisher-2145"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/08/23/adobe-air-launchpad-helps-you-creating-air-appsprojects/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/wjsjD0egmVM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/08/23/adobe-air-launchpad-helps-you-creating-air-appsprojects/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/08/23/adobe-air-launchpad-helps-you-creating-air-appsprojects/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=adobe-air-launchpad-helps-you-creating-air-appsprojects</feedburner:origLink></item>
		<item>
		<title>LiveCycle Collaboration Service and Screen Sharing</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/ZpLZxuHniUk/</link>
		<comments>http://corlan.org/2010/08/18/livecycle-collaboration-service-and-screen-sharing/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 07:43:32 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Others]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2138</guid>
		<description><![CDATA[




			
				
			
		
LiveCycle Collaboration Service just got three new features that I&#8217;m pretty sure will make you very happy:

Screen Sharing. Yes, this is exactly what the names implies. Now, you can add screen sharing to your applications. Amazingly cool isn&#8217;t it?
Recording and Playback. You can record and download your collaborative session, and then playback this recording. You [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/08/18/livecycle-collaboration-service-and-screen-sharing/&title=LiveCycle Collaboration Service and Screen Sharing&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F18%2Flivecycle-collaboration-service-and-screen-sharing%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F08%2F18%2Flivecycle-collaboration-service-and-screen-sharing%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>LiveCycle Collaboration Service just got three new features that I&#8217;m pretty sure will make you very happy:</p>
<ul>
<li>Screen Sharing. Yes, this is exactly what the names implies. Now, you can add screen sharing to your applications. Amazingly cool isn&#8217;t it?</li>
<li>Recording and Playback. You can record and download your collaborative session, and then playback this recording. You will see the data, audio, and video.</li>
<li>LCCS JavaScript SDK. We added JavaScript APIs and you can code your collaborative service using JavaScript. Though you still have to embed a SWF in your HTML page.</li>
</ul>
<p><img class="aligncenter size-full wp-image-2139" title="lccs_128" src="http://corlan.org/wp-content/uploads/2010/08/lccs_128.png" alt="" width="128" height="128" /></p>
<p>We also changed the domain name to something more meaningful: <a href="http://collaboration.adobelivecycle.com" target="_blank">http://collaboration.adobelivecycle.com</a> and we have a new logo for this service :).</p>
<p>You can read more on the team&#8217;s <a href="http://blogs.adobe.com/collabmethods/2010/08/screen-sharing-and-recording-august-feature-tsunami.html" target="_blank">blog</a>, and my fellow evangelist, Tom Krcha, has examples on his <a href="http://www.flashrealtime.com/screen-sharing-in-flash-now-available/" target="_blank">blog</a>. Sign up <a href="http://collaboration.adobelivecycle.com/" target="_blank">here</a> and get the SDK, use these <a href="http://forums.adobe.com/community/livecycle/lccs" target="_blank">forums</a> to post questions and feedback, and learn about it <a href="http://www.adobe.com/flashplatform/services/collaboration/" target="_blank">here</a>.</p>
<div class="shr-publisher-2138"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/08/18/livecycle-collaboration-service-and-screen-sharing/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/ZpLZxuHniUk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/08/18/livecycle-collaboration-service-and-screen-sharing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/08/18/livecycle-collaboration-service-and-screen-sharing/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=livecycle-collaboration-service-and-screen-sharing</feedburner:origLink></item>
		<item>
		<title>Upcoming webinars on the Flash Platform</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/I7I7rA3mn1E/</link>
		<comments>http://corlan.org/2010/08/17/upcoming-webinars-on-the-flash-platform/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 14:43:20 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Conferences]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2132</guid>
		<description><![CDATA[




			
				
			
		
The summer is almost over (at least in the northern hemisphere :D) which means you are in one of these two situations: either you just came back from vacation or you&#8217;re about to take one. Either way, I think you&#8217;ll find (some of) the webinars we are doing this month quite interesting. As usually, they [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/08/17/upcoming-webinars-on-the-flash-platform/&title=Upcoming webinars on the Flash Platform&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F17%2Fupcoming-webinars-on-the-flash-platform%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F08%2F17%2Fupcoming-webinars-on-the-flash-platform%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>The summer is almost over (at least in the northern hemisphere :D) which means you are in one of these two situations: either you just came back from vacation or you&#8217;re about to take one. Either way, I think you&#8217;ll find (some of) the webinars we are doing this month quite interesting. As usually, they are free; you just have to sign up and show up. A word of warning: because all four of these webinars are delivered by EMEA platform evangelist, we decided to schedule them in such a way that works for Europeans.</p>
<p>Here is the list:</p>
<ul>
<li><a href="http://multiscreenapps.eventbrite.com/" target="_blank">Building Multi-Screen / Interconnected apps for Android and desktops</a> (Mihai Corlan) &#8211; Friday, Augst 20</li>
<li><a href="http://doctrinezendflash.eventbrite.com/" target="_blank">Summer Cocktail: Doctrine 2, Zend Framework, Flex, and Flash Builder</a> (Mihai Corlan)- Tuesday, August 24</li>
<li><a href="http://advancedp2p.eventbrite.com/" target="_blank">Advanced P2P programming in Flash</a> (Tom Krcha) &#8211; Friday, August 27</li>
<li><a href="http://flexandswiz.eventbrite.com/" target="_blank">Presentation Model pattern with Flex and Swiz Framework</a> (Piotr Walczyszyn) &#8211; Tuesday, August 31, 2010</li>
</ul>
<p>Enjoy!</p>
<div class="shr-publisher-2132"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/08/17/upcoming-webinars-on-the-flash-platform/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/I7I7rA3mn1E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/08/17/upcoming-webinars-on-the-flash-platform/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/08/17/upcoming-webinars-on-the-flash-platform/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=upcoming-webinars-on-the-flash-platform</feedburner:origLink></item>
		<item>
		<title>New Flash Player release enables H.264 GPU decoding on Mac OS X</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/4cFhvjsBx78/</link>
		<comments>http://corlan.org/2010/08/11/new-flash-player-release-enables-h-264-gpu-decoding-on-macosx/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 06:52:42 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Flash Player]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2123</guid>
		<description><![CDATA[




			
				
			
		
We&#8217;ve just released a new version of Flash Player: 10.1.82.76, which includes support for H.264 video GPU decoding. This was previously available in a beta release code-named Gala. On top of this new cool feature, there were a number of bug fixes, so you definitely you should install it as soon as possible.
You can get [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/08/11/new-flash-player-release-enables-h-264-gpu-decoding-on-macosx/&title=New Flash Player release enables H.264 GPU decoding on Mac OS X&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F11%2Fnew-flash-player-release-enables-h-264-gpu-decoding-on-macosx%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F08%2F11%2Fnew-flash-player-release-enables-h-264-gpu-decoding-on-macosx%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>We&#8217;ve just released a new version of Flash Player: 10.1.82.76, which includes support for H.264 video GPU decoding. This was previously available in a beta release code-named Gala. On top of this new cool feature, there were a number of bug fixes, so you definitely you should install it as soon as possible.</p>
<p>You can get the <a href="http://www.adobe.com/support/flashplayer/downloads.html" target="_blank">installers</a> from here (including debugging versions). You can read about the security updates <a href="http://www.adobe.com/devnet/flashplayer/articles/flash_player10.1.82_security_update.html" target="_blank">here</a>.</p>
<p>LATER UPDATE:</p>
<p>I almost forgot to tell you about the new version of Adobe AIR (2.0.3). Like in the case of Flash Player, besides a number of bug fixes, we added support for GZIP compression for Windows (this was already available for Mac OS X and Linux).</p>
<p>You can get the runtime from <a href="http://get.adobe.com/air/" target="_blank">here</a>.</p>
<div class="shr-publisher-2123"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/08/11/new-flash-player-release-enables-h-264-gpu-decoding-on-macosx/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/4cFhvjsBx78" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/08/11/new-flash-player-release-enables-h-264-gpu-decoding-on-macosx/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/08/11/new-flash-player-release-enables-h-264-gpu-decoding-on-macosx/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=new-flash-player-release-enables-h-264-gpu-decoding-on-macosx</feedburner:origLink></item>
		<item>
		<title>Working with Doctrine 2, Flex, Zend AMF, and Flash Builder</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/Ct1xzBTzJ2A/</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[Flash Builder]]></category>
		<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 id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/08/05/working-with-doctrine-2-flex-zend-amf-and-flash-builder/&title=Working with Doctrine 2, Flex, Zend AMF, and Flash Builder&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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" 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>
<div class="shr-publisher-2115"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/08/05/working-with-doctrine-2-flex-zend-amf-and-flash-builder/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/Ct1xzBTzJ2A" height="1" width="1"/>]]></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>9</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/08/05/working-with-doctrine-2-flex-zend-amf-and-flash-builder/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=working-with-doctrine-2-flex-zend-amf-and-flash-builder</feedburner:origLink></item>
		<item>
		<title>50 resources to get up to speed with the Flash Platform</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/grIeVbLxON4/</link>
		<comments>http://corlan.org/2010/07/29/50-resources-to-get-up-to-speed-with-the-flash-platform/#comments</comments>
		<pubDate>Thu, 29 Jul 2010 13:57:10 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Flash Builder]]></category>
		<category><![CDATA[Flash Player]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2078</guid>
		<description><![CDATA[




			
				
			
		
For the past six months we&#8217;ve been rolling out a lot of goodies, some of them in the form of final releases, others as betas. It&#8217;s no wonder you have to spend some time in order to get up to speed with the latest features of AIR 2, Flash Player 10.1 for Android, AIR 2.5, [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/07/29/50-resources-to-get-up-to-speed-with-the-flash-platform/&title=50 resources to get up to speed with the Flash Platform&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F07%2F29%2F50-resources-to-get-up-to-speed-with-the-flash-platform%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F07%2F29%2F50-resources-to-get-up-to-speed-with-the-flash-platform%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>For the past six months we&#8217;ve been rolling out a lot of goodies, some of them in the form of final releases, others as betas. It&#8217;s no wonder you have to spend some time in order to get up to speed with the latest features of AIR 2, Flash Player 10.1 for Android, AIR 2.5, Flex 4, or Flash Builder 4. Thus, I thought it&#8217;d be a great idea to put together a list of resources to help you learn about these goodies.</p>
<p>So here I go, in no particular order.</p>
<h2>Peer 2 Peer</h2>
<p>Flash Player 10.1 and Adobe AIR 2 brings new capabilities to the table when it comes to Peer 2 Peer. The best resource to learn about this is my fellow evangelist Tom Krcha (some say his dreams are multicasted, but only a few are lucky enough to receive them :D):</p>
<ul>
<li><a href="http://www.flashrealtime.com/multicast-explained-flash-101-p2p/" target="_blank">Multicast Explained in Flash Player 10.1</a></li>
<li><a href="http://www.flashrealtime.com/file-share-object-replication-flash-p2p/" target="_blank">File sharing over P2P in Flash Player 10.1 with Object Replication</a></li>
<li><a href="http://www.flashrealtime.com/p2p-groupspecifier-explained-1/" target="_blank">P2P GroupSpecifier Class Explained</a></li>
<li><a href="http://www.flashrealtime.com/directed-routing-explained-flash-p2p/" target="_blank">Direct Routing Explained in Flash Player 10.1</a></li>
<li><a href="http://www.flashrealtime.com/simple-chat-p2p-netgroup-rtmfp/" target="_blank">Simple chat with P2P NetGroup in Flash Player 10.1</a></li>
</ul>
<h2>Flex and server side technologies</h2>
<ul>
<li><a href="http://www.adobe.com/devnet/flex/articles/traderdesktop.html" target="_blank">Christophe Coenraets wrote about tuning client-side performance using Flex 4 and LiveCycle Data Services</a></li>
<li><a href="http://www.adobe.com/devnet/flex/articles/crud_flex_php_zend.html" target="_blank">Ryan Stewart&#8217;s article on creating a basic CRUD application using Flex and PHP with Zend AMF</a></li>
<li>If you prefer to use the Data Centric Development features of Flash Builder when working with Flex and PHP check out this <a href="http://www.adobe.com/devnet/flex/articles/flashbuilder4_php_part1.html" target="_blank">article</a></li>
<li><a href="http://corlan.org/debugging-flex-and-php/" target="_blank">Debugging Flex and PHP projects with Flash Builder 4 and Eclipse PDT/XDebug</a></li>
<li><a href="http://www.adobe.com/devnet/flex/articles/flashbuilder_webservice_dotnet.html" target="_blank">Using Flash Builder 4 to build a Flex application that consumes a .NET-based web service written in C#</a></li>
</ul>
<h2>AIR 2</h2>
<ul>
<li><a href="http://www.adobe.com/devnet/flashplayer/articles/fplayer10.1_air2_security_changes.html" target="_blank">Understanding the security changes in Flash Player 10.1 and AIR 2</a></li>
<li><a href="http://coenraets.org/blog/2010/07/creating-a-web-server-using-the-new-server-socket-api-in-air-2/" target="_blank">Creating a Web Server using the new Server Socket API in AIR 2</a></li>
<li><a href="http://coenraets.org/blog/2010/06/air-2-excel-sample-app-updated-for-air-2-ga/" target="_blank">Exploring the &#8220;open with default application&#8221; API</a></li>
<li>Exploring the Native Processes API: <a href="http://corlan.org/2009/11/30/magnifying-glass-air-2-application-or-how-to-communicate-with-a-java-program-from-air/" target="_blank">here</a>, <a href="http://www.adobe.com/devnet/air/flex/articles/air_screenrecording.html" target="_blank">here</a>, <a href="http://www.gotoandlearn.com/play.php?id=125">here</a>, and <a href="http://www.gotoandlearn.com/play.php?id=126" target="_blank">here</a></li>
<li><a href="http://www.adobe.com/devnet/air/flex/articles/retrieving_network_interfaces.html" target="_blank">Retrieving a list of network interfaces in Adobe AIR 2</a></li>
<li><a href="http://www.adobe.com/devnet/air/flex/articles/creating_socket_server.html" target="_blank">Creating a socket server in Adobe AIR 2</a></li>
<li>
<div id="_mcePaste"><a href="http://www.adobe.com/devnet/air/flex/articles/resolving_dns_records.html" target="_blank">Resolving DNS records in Adobe AIR 2</a></div>
</li>
<li><a href="http://www.adobe.com/devnet/air/flex/articles/using_file_promises.html" target="_blank">Using drag-and-drop support of remote files in Adobe AIR 2</a></li>
<li><a href="http://www.adobe.com/devnet/air/flex/articles/writing_multiscreen_air_apps.html" target="_blank">Writing multiscreen AIR apps</a></li>
<li><a href="http://www.riagora.com/2010/06/air-2-0-and-the-enterprise/" target="_blank">AIR 2 and Enterprise</a></li>
<li><a href="http://www.adobe.com/devnet/coldfusion/articles/offline_air_orm.html" target="_blank">Developing AIR offline applications using the ColdFusion 9.0.1 ActionScript ORM Library</a></li>
<li><a href="http://www.adobe.com/devnet/air/articles/10_tips_building_on_air.html" target="_blank">Ten tips for building better Adobe AIR applications</a></li>
</ul>
<h2>AIR/Flash Player 10.1 and Android</h2>
<ul>
<li><a href="http://www.flashmobileblog.com/2010/07/17/p2p-video-calls-on-android/" target="_blank">Mark Doherty&#8217;s P2P Video Calls on Android tutorial</a></li>
<li><a href="http://www.flashmobileblog.com/2010/07/17/air2-5-stagewebview-demo-oauth-support/" target="_blank">AIR 2.5 StageWebView demo</a></li>
<li><a href="http://www.flashmobileblog.com/2010/06/15/eva-geoservices-component-source/" target="_blank">Geolocation in AIR</a></li>
<li><a href="http://coenraets.org/blog/2010/07/video-chat-for-android-in-30-lines-of-code/" target="_blank">Video chat for Android using LiveCycle Collaboration Service and AIR</a></li>
<li>Android apps that connects to desktop apps using Peer 2 Peer: <a href="http://corlan.org/2010/07/02/creating-multi-screen-apps-for-android-and-desktop-using-air/" target="_blank">here</a> and <a href="http://corlan.org/2010/07/08/androidpictures-or-how-to-share-phone-pictures-with-desktops/" target="_blank">here</a></li>
<li><a href="http://www.gotoandlearn.com/play.php?id=123" target="_blank">Setting up the tools for creating AIR for Android apps</a> and <a href="http://www.gotoandlearn.com/play.php?id=124" target="_blank">accessing the camera from AIR</a></li>
<li><a href="http://coenraets.org/blog/2010/07/android-trader-desktop-with-flex-and-air-updated-for-froyo-source-code-available/" target="_blank">Android Trader Desktop with Flex and AIR for Android</a></li>
<li><a href="http://coenraets.org/blog/2010/07/voicenotes-for-android-sample-app-using-flex-air-and-the-microphone-api/" target="_blank">“VoiceNotes for Android”: Sample App using Flex, AIR, and the Microphone API</a></li>
<li><a href="http://www.webkitchen.be/package-assistant-pro/" target="_blank">Serge Jespers&#8217;s native installers packager</a></li>
</ul>
<h2>Flex 4</h2>
<ul>
<li><a href="http://www.adobe.com/devnet/flex/articles/flex4sdk_whatsnew.html" target="_blank">What&#8217;s new in Flex 4</a></li>
<li><a href="http://www.adobe.com/devnet/flex/articles/flex3and4_differences.html" target="_blank">Differences between Flex 3 and Flex 4</a></li>
<li><a href="http://www.adobe.com/devnet/flex/articles/flex4_skinning.html" target="_blank">Skinning in Flex 4</a></li>
<li><a href="http://www.adobe.com/devnet/flex/articles/spark_layouts.html" target="_blank">Introduction to Flex 4 (Spark) layouts</a></li>
<li><a href="http://www.adobe.com/devnet/flex/articles/flex4_effects_pt1.html" target="_blank">New Animation Engine</a></li>
<li><a href="http://www.riagora.com/2010/07/flex-and-layout-mirroring/" target="_blank">Michaël Chaize&#8217;s layout mirroring article</a></li>
<li><a href="http://www.riaspace.com/2010/03/adobe-tv-styling-flex-4-components-with-flash-builder-4/" target="_blank">Styling Flex 3 components with Flash Builder 4</a></li>
<li><a href="http://tv.adobe.com/watch/codedependent/image-zoom-effect-in-flex-4/" target="_blank">Image Zoom Effect</a> and <a href="http://tv.adobe.com/watch/codedependent/animating-filters-in-flex-4-part-i/" target="_blank">Animating Filters</a> by Chet Haase</li>
</ul>
<h2>Other Flash Builder 4 related resources</h2>
<ul>
<li><a href="http://www.adobe.com/devnet/flex/articles/flashbuilder4_whatsnew.html" target="_blank">What&#8217;s new in Flash Builder 4</a></li>
<li><a href="http://www.adobe.com/devnet/flex/articles/flashbuilder_dcd_parsley.html" target="_blank">Using Data-Centric features with Parsley (and other frameworks)</a></li>
<li><a href="http://www.adobe.com/devnet/flex/articles/flashbuilder_tdd.html" target="_blank">Test Driven Development with Flash Builder 4 and FlexUnit</a></li>
<li><a href="http://corlan.org/2010/07/15/flash-builders-lost-features-profiler/" target="_blank">Using Flash Builder&#8217;s Profiler</a></li>
<li><a href="http://www.adobe.com/devnet/flex/articles/flexbuilder3_to_flashbuilder4.html" target="_blank">Moving existing Flex projects from Flex Builder 3 to Flash Builder 4</a></li>
</ul>
<p>Enjoy!</p>
<div class="shr-publisher-2078"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/07/29/50-resources-to-get-up-to-speed-with-the-flash-platform/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/grIeVbLxON4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/07/29/50-resources-to-get-up-to-speed-with-the-flash-platform/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/07/29/50-resources-to-get-up-to-speed-with-the-flash-platform/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=50-resources-to-get-up-to-speed-with-the-flash-platform</feedburner:origLink></item>
		<item>
		<title>Shibuya / Melrose is available on Adobe Lab</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/x9JrgbPjXm0/</link>
		<comments>http://corlan.org/2010/07/22/shibuya-melrose-is-available-on-adobe-lab/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 08:26:35 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[AIR]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2072</guid>
		<description><![CDATA[




			
				
			
		
What is Melrose (formerly known as Shibuya)? It is a service provided by Adobe that helps you monetize your AIR applications. Pretty cool, isn&#8217;t it? Still, what exactly does it do for you? In a nutshell it helps you push your AIR application to millions of people and it handles all the details related to [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/07/22/shibuya-melrose-is-available-on-adobe-lab/&title=Shibuya / Melrose is available on Adobe Lab&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F07%2F22%2Fshibuya-melrose-is-available-on-adobe-lab%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F07%2F22%2Fshibuya-melrose-is-available-on-adobe-lab%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>What is Melrose (formerly known as Shibuya)? It is a service provided by Adobe that helps you monetize your AIR applications. Pretty cool, isn&#8217;t it? Still, what exactly does it do for you? In a nutshell it helps you push your AIR application to millions of people and it handles all the details related to charging money for the application and setting up trial periods. From a code perspective, you add a library and couple of lines of code to your application to enable all these features.</p>
<p>For now, there are two storefronts available for you: Adobe AIR Marketplace and Intel AppUp center. You can use Melrose in 47 countries for now (it is still in private beta): Argentina, Australia, Austria, Belgium, Brazil, Bulgaria, Canada,  Colombia, Cyprus, Czech Republic, Denmark, Estonia, Finland, France,  Germany, Greece, Hungary, India, Ireland, Israel, Italy, Japan,  Lithuania, Luxembourg, Malta, Mexico, Netherlands, New Zealand, Norway,  People&#8217;s Republic of China, Poland, Portugal, Romania, Russia, Serbia,  Singapore, Slovenia, South Africa, South Korea, Spain, Sweden,  Switzerland, Taiwan, Turkey, Ukraine, United Kingdom and United States.</p>
<p>If you choose to charge money for your application, then you get 70% of the revenue (there is a minimum price of $2.99 for any app you want to sell). You get the money on a monthly basis, provided you sold for more than $100 in the past 30 days. There are no charges if you choose to give away your application for free.</p>
<p>And finally, you have access to a dashboard where you can see information like number of trials, number of purchases, and revenue.</p>
<p>You can sign up for Melrose <a href="http://labs.adobe.com/technologies/melrose/" target="_blank">here</a>, on Adobe Labs. Sign up and let us know what do you think!</p>
<div class="shr-publisher-2072"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/07/22/shibuya-melrose-is-available-on-adobe-lab/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/x9JrgbPjXm0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/07/22/shibuya-melrose-is-available-on-adobe-lab/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/07/22/shibuya-melrose-is-available-on-adobe-lab/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=shibuya-melrose-is-available-on-adobe-lab</feedburner:origLink></item>
		<item>
		<title>Enterprise Cafe</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/CZkSg9-5Bdc/</link>
		<comments>http://corlan.org/2010/07/19/enterprise-cafe/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 07:47:51 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Others]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2065</guid>
		<description><![CDATA[




			
				
			
		
I thought it would be cool to talk about this app because chances are that you haven&#8217;t heard about Enterprise Cafe. So what is Enterprise Cafe? It is an AIR application (:D) that aggregates a big number of resources on the following topics: LiveCycle, Acrobat, Connect, ColdFusion, Flash Platform.

Once you log in using your Adobe [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/07/19/enterprise-cafe/&title=Enterprise Cafe&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F07%2F19%2Fenterprise-cafe%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F07%2F19%2Fenterprise-cafe%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>I thought it would be cool to talk about this app because chances are that you haven&#8217;t heard about Enterprise Cafe. So what is Enterprise Cafe? It is an AIR application (:D) that aggregates a big number of resources on the following topics: LiveCycle, Acrobat, Connect, ColdFusion, Flash Platform.</p>
<p><img class="aligncenter size-medium wp-image-2066" title="ecafe" src="http://corlan.org/wp-content/uploads/2010/07/ecafe-300x223.jpg" alt="" width="300" height="223" /></p>
<p>Once you log in using your Adobe ID account and choose, for example, the Flash Platform, you&#8217;ll see a screen like this:</p>
<p><img class="aligncenter size-medium wp-image-2067" title="ecafe-2" src="http://corlan.org/wp-content/uploads/2010/07/ecafe-2-300x219.jpg" alt="" width="300" height="219" /></p>
<p>Enterprise Cafe helps you to stay in touch with the community (you can access Adobe forums from this app), receive news (you&#8217;ll find the success stories posted here very interesting), check out the latest blog posts and videos using the incorporated RSS reader and Adobe TV section, or check for Adobe events.</p>
<p>If you want to convince your team or boss about the value of the Flash Platform, then you should definitely take a look at this app. You&#8217;ll find the information you need to convince them.</p>
<h2>Install Enterprise Cafe</h2>
<p>You can download the application from <a href="http://www.adobe.com/devnet/enterprise/cafe/index.html" target="_blank">here</a>.</p>
<div class="shr-publisher-2065"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/07/19/enterprise-cafe/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/CZkSg9-5Bdc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/07/19/enterprise-cafe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/07/19/enterprise-cafe/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=enterprise-cafe</feedburner:origLink></item>
		<item>
		<title>Flash Builder’s Lost Features: Profiler</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/24kigL5CmnI/</link>
		<comments>http://corlan.org/2010/07/15/flash-builders-lost-features-profiler/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 13:21:09 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Flash Builder]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2053</guid>
		<description><![CDATA[




			
				
			
		
Here is the second episode of the Flash Builder&#8217;s Lost Features show. This time I chose to talk about Flash Builder&#8217;s profiler and give you enough info to feel comfortable using it if it&#8217;s new to you. Profiler helps you to locate memory leaks, identify excessive object allocation, or analyze execution times.
With the extension of [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/07/15/flash-builders-lost-features-profiler/&title=Flash Builder&#8217;s Lost Features: Profiler&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F07%2F15%2Fflash-builders-lost-features-profiler%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F07%2F15%2Fflash-builders-lost-features-profiler%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Here is the second episode of the Flash Builder&#8217;s Lost Features show. This time I chose to talk about Flash Builder&#8217;s profiler and give you enough info to feel comfortable using it if it&#8217;s new to you. Profiler helps you to locate memory leaks, identify excessive object allocation, or analyze execution times.</p>
<p>With the extension of the Flash Platform on mobile devices, I think that it&#8217;s more important than ever to build Flash applications that run efficiently for a long time. Here is the video (you can watch the video in a higher resolution <a href="http://vimeo.com/13359564" target="_blank">here</a>).</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="300" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=13359564&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed type="application/x-shockwave-flash" width="400" height="300" src="http://vimeo.com/moogaloop.swf?clip_id=13359564&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>If you want to read more about the &#8220;art&#8221; of profiling then please take the time to read the official (<a href="http://help.adobe.com/en_US/flashbuilder/using/WS6f97d7caa66ef6eb1e63e3d11b6c4d0d21-7edf.html" target="_blank">here</a> and <a href="http://help.adobe.com/en_US/flashbuilder/using/WS6f97d7caa66ef6eb1e63e3d11b6c4d0169-7ff6.html#WS6f97d7caa66ef6eb1e63e3d11b6c4d0d21-7ee2" target="_blank">here</a>) and Ilan Avigdor&#8217;s <a href="http://www.tikalk.com/flex/solving-memory-leaks-using-flash-builder-4-profiler" target="_blank">article</a>.</p>
<div class="shr-publisher-2053"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/07/15/flash-builders-lost-features-profiler/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/24kigL5CmnI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/07/15/flash-builders-lost-features-profiler/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/07/15/flash-builders-lost-features-profiler/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=flash-builders-lost-features-profiler</feedburner:origLink></item>
		<item>
		<title>Flash for mobile contests</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/Is2ZkXbSau4/</link>
		<comments>http://corlan.org/2010/07/15/flash-for-mobile-contests/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 08:29:37 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Flash Player]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2049</guid>
		<description><![CDATA[




			
				
			
		
This summer you have many contests to pick from if you want to create Flash content for mobile (Android 2.2) and win something while doing it. You can win fame/money/software/mobile devices &#8212; not neccesary in that order and not all at once&#8211; but you get the point :D.

For more details, check out these contests:

Kongregate Mobile [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/07/15/flash-for-mobile-contests/&title=Flash for mobile contests&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F07%2F15%2Fflash-for-mobile-contests%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F07%2F15%2Fflash-for-mobile-contests%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>This summer you have many contests to pick from if you want to create Flash content for mobile (Android 2.2) and win something while doing it. You can win fame/money/software/mobile devices &#8212; not neccesary in that order and not all at once&#8211; but you get the point :D.</p>
<p><img class="alignnone size-full wp-image-2050" title="made-for-mobile" src="http://corlan.org/wp-content/uploads/2010/07/made-for-mobile.jpg" alt="" width="600" height="193" /></p>
<p>For more details, check out these contests:</p>
<ul>
<li><a href="http://www.kongregate.com/pages/mobile-game-contest" target="_blank">Kongregate Mobile Flash Game Contest</a> (almost $30,000 in prizes)</li>
<li><a href="http://www.mochimedia.com/contest/jul10" target="_blank">Mochimedia Made for Mobile Contest</a> ($20,000 in cash plus CS5 Master Suite licenses)</li>
<li><a href="http://www.flashgamelicense.com/sponsor_pages/adobe/#intro" target="_blank">Cell Your Flash Game</a> ($30,000 in prizes)</li>
<li><a href="http://www.flashrealtime.com/summer-air-mobile-contest-2010/" target="_blank">Adobe Czech Republic AIR Mobile Contest 2010</a> (Nexus One phones and software)</li>
</ul>
<p>Good luck!</p>
<div class="shr-publisher-2049"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/07/15/flash-for-mobile-contests/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/Is2ZkXbSau4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/07/15/flash-for-mobile-contests/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/07/15/flash-for-mobile-contests/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=flash-for-mobile-contests</feedburner:origLink></item>
		<item>
		<title>Unlocking the true potential of smartphones</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/A3V6uifQF2s/</link>
		<comments>http://corlan.org/2010/07/12/unlocking-the-true-potential-of-the-smartphones/#comments</comments>
		<pubDate>Mon, 12 Jul 2010 14:06:50 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Others]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2044</guid>
		<description><![CDATA[




			
				
			
		
Lately, I&#8217;ve been thinking and working a lot with multiple-screen applications that run across desktop and Android devices. The reason for doing this is pretty simple: my first four computers were less powerful than the current smartphone I&#8217;m using these days.
And still I was doing far more things then I do with my phone now. [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/07/12/unlocking-the-true-potential-of-the-smartphones/&title=Unlocking the true potential of smartphones&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F07%2F12%2Funlocking-the-true-potential-of-the-smartphones%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F07%2F12%2Funlocking-the-true-potential-of-the-smartphones%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Lately, I&#8217;ve been thinking and working a lot with multiple-screen applications that run across desktop and Android devices. The reason for doing this is pretty simple: my first four computers were less powerful than the current smartphone I&#8217;m using these days.</p>
<p>And still I was doing far more things then I do with my phone now. So what are we using the smartphone for? I think we use a smartphone mainly for: making phone calls, Internet browsing, mailing, GPS, listening to music, and playing games. But is this all we can do? I think not.</p>
<p>One of my dreams is to be able to use my phone for tasks that I accomplished using the same tools 5-10 years ago. Let me give you some examples: we all have at home a number of remote controls: for the TV sets, DVD player, sound system, Air Conditioner system, TV set-top-box and the list could go on and on. The basic interaction between us and these devices hasn&#8217;t changed lately. Maybe you could replace some of these remote controls with an expensive one, touch based. This is only a compromise. We should be able to use our smartphones for these kinds of tasks and much more.</p>
<p>I mean we all carry the phones all day; they have beautiful screens and you can interact with them using the touchscreen interface. The biggest issue that prevents us from doing this is that most of the systems we are using today don&#8217;t talk the same language, nor do they offer a common API to interconnect them.</p>
<p>Hopefully this is starting to change. With the extension of the Flash Platform on smartphones (for now only on Android phones, but soon it will be available on other phones too) and on the TV sets/set-top-boxes we are one step closer to achieving a unified system. So instead of relying on manufacturers to expose a common API, we can leverage a common runtime that runs across devices. Imagine that you&#8217;d be able to use your smartphone for:</p>
<ul>
<li>Checking the current temperature in your home (even when you are not at home) and starting/stopping/reprogramming the AC</li>
<li>Being able to change TV channels from your phone</li>
<li>Being able to check the schedule and make a recording right from your phone</li>
<li>Start recording a program on your way back home because you&#8217;ll be late and don&#8217;t want to miss the NBA final</li>
<li>Controlling your music system from any room or even from your lawn</li>
<li>Checking the grocery list your wife wrote two days ago while shopping</li>
</ul>
<p>Some of these are already possible using some expensive home automation systems. Others are possible using a cloud solution. I think the ubiquity of the Flash Platform on a larger number of different devices and the huge number of Flash developers will make many of these available in the near future for everyone who cares and decides wisely what devices to buy.Why? Because on one hand it will be cheaper to develop a solution for multiple devices due to one common runtime and one language/framework to learn and, on the other hand, the Flash community is full of people who are not afraid to dream and who love to push the limits (just have a look at projects like <a href="http://www.gskinner.com/blog/archives/2010/06/air_for_android.html" target="_blank">Nexus One Wireless Slot Car Gas Pedal</a>, <a href="http://www.audiotool.com/" target="_blank">Audiotool</a>, <a href="http://www.screenergy.com" target="_blank">Screenergy</a>, or <a href="http://www.creaza.com" target="_blank">Creaza.com</a> if you don&#8217;t believe me).</p>
<p>Until then, I will keep dreaming and try to build some of these myself. I&#8217;m looking forward to Google TV and the first TV sets that &#8220;speak&#8221; Flash.</p>
<p>What do you think?</p>
<p>LATER UPDATE: I&#8217;ve just seen this cool Android app build with AIR and Flex 4 that controls Freebox STB: <a href="http://chubby75.com/blog/?p=9" target="_blank">http://chubby75.com/blog/?p=9</a></p>
<div class="shr-publisher-2044"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/07/12/unlocking-the-true-potential-of-the-smartphones/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/A3V6uifQF2s" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/07/12/unlocking-the-true-potential-of-the-smartphones/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/07/12/unlocking-the-true-potential-of-the-smartphones/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=unlocking-the-true-potential-of-the-smartphones</feedburner:origLink></item>
		<item>
		<title>AIR apps for viewing Android pictures on desktops</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/6Rg4ls121d4/</link>
		<comments>http://corlan.org/2010/07/08/androidpictures-or-how-to-share-phone-pictures-with-desktops/#comments</comments>
		<pubDate>Thu, 08 Jul 2010 13:29:33 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2014</guid>
		<description><![CDATA[




			
				
			
		
This week I had time to play with another idea for Android/Desktop applications: a picture viewer. My friend Alex Chiculita from the AIR team gave me this idea. A couple of weeks ago he played with a multi-screen application that let you load a picture from a device and send the picture to all the [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/07/08/androidpictures-or-how-to-share-phone-pictures-with-desktops/&title=AIR apps for viewing Android pictures on desktops&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F07%2F08%2Fandroidpictures-or-how-to-share-phone-pictures-with-desktops%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F07%2F08%2Fandroidpictures-or-how-to-share-phone-pictures-with-desktops%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>This week I had time to play with another idea for Android/Desktop applications: a picture viewer. My friend Alex Chiculita from the AIR team gave me this idea. A couple of weeks ago he played with a multi-screen application that let you load a picture from a device and send the picture to all the other devices connected to the same Wi-Fi network (the app runs on Android, Windows, MacOS, and Linux).</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/07/icons-pictureviewer.png"><img class="aligncenter size-full wp-image-2017" title="PicturesViewer" src="http://corlan.org/wp-content/uploads/2010/07/icons-pictureviewer.png" border="0" alt="" width="140" height="140" /></a></p>
<p>While playing with his application I realized that I could transform it into something more helpful (at least for me). Here is the challenge: we all use our smartphones for a lot of things, including taking pictures. Having a decent digital camera (this is what a smartphone became lately on top of a mobile phone) with you all the time means you can take interesting pictures. And usually you want to show these pictures to your friends or family. However, here is the problem: while taking pictures is extremely easy, sharing them involves cables,  Bluetooth, or seeing the picture on the phone&#8217;s screen.</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/07/androidpictures_1.jpg"><img class="alignnone size-medium wp-image-2018" title="AndroidPictures Main Screen" src="http://corlan.org/wp-content/uploads/2010/07/androidpictures_1-180x300.jpg" border="0" alt="" width="180" height="300" /></a> <a href="http://corlan.org/wp-content/uploads/2010/07/androidpictures_2.jpg"><img class="alignnone size-medium wp-image-2019" title="AndroidPictures Picture View Screen" src="http://corlan.org/wp-content/uploads/2010/07/androidpictures_2-180x300.jpg" border="0" alt="" width="180" height="300" /></a> <a href="http://corlan.org/wp-content/uploads/2010/07/androidpictures_3.jpg"><img class="alignnone size-medium wp-image-2020" title="AndroidPictures Interacting with the picture" src="http://corlan.org/wp-content/uploads/2010/07/androidpictures_3-179x300.jpg" border="0" alt="" width="179" height="300" /></a></p>
<p>My solution to this problem is AndroidPictures (the above pictures show AndroidPictures in action on my mobile). This Android application lets you browse through the pictures taken with the phone and scale/rotate/pan them. On the desktop, you use the companion AIR application for AndroidPictures, which displays the pictures sent by the Android application. All you have to do to see the pictures with your family is:</p>
<ul>
<li> connect your Android phone to the WI-FI network;</li>
<li>start the AndroidPictures app on your Android phone, and start the PicturesViewer app on one of/all your computers;</li>
<li>what you see on your mobile phone will be replicated on all connected computers.</li>
</ul>
<p>Watch the video below to see how it works.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="300" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=13191203&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed type="application/x-shockwave-flash" width="400" height="300" src="http://vimeo.com/moogaloop.swf?clip_id=13191203&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<h2>The making of</h2>
<p>I used Adobe AIR and Flex 4.1 for creating the Android and desktop applications. In order to connect the Android application to the desktop apps I used Peer-to-Peer direct routing (the same approach used in my previous <a href="http://corlan.org/2010/07/02/creating-multi-screen-apps-for-android-and-desktop-using-air/" target="_blank">app</a>). As I already explained, if your local subnet (for example your home Wi-Fi) supports broadcasting then you can create a NetConnection without using Stratus or a Flash Media Server (you connect the NetConnection to &#8220;rtmfp:&#8221;). This is one of the new features available in Flash Player 10.1 and Adobe AIR 2.</p>
<p>Once you have the clients connected, you can send messages from any one to all of them. And the cool thing about using this approach as opposed to Socket servers is that you don&#8217;t have to manually manage all the clients. Your program sends a message and the clients decide how to handle the message. You simply don&#8217;t care how many clients are connected. You can read more on my fellow evangelist Tom&#8217;s <a href="http://www.flashrealtime.com/directed-routing-explained-flash-p2p/" target="_blank">blog</a>.</p>
<p>Because I wanted to use this approach for other apps, I created a simple library (you can get the library&#8217;s source code from <a href="http://corlan.org/downloads/androidpictures/AndroidPicturesProjects.zip">here</a>; unzip the archive and import the PeerToPeer.fxpl project in Flash Builder). You&#8217;ll find three ActionScript classes, and the magic happens inside of MultiCastingService class. The public interface of this service is:</p>
<ul>
<li>isReady</li>
<li>neighborCount</li>
<li>userName</li>
<li>connect()</li>
<li>disconnect()</li>
<li>post()</li>
</ul>
<p>The service throws these events:</p>
<ul>
<li>ServiceEvent.CONNECTED</li>
<li>ServiceEvent.DISCONNECTED</li>
<li>ServiceEvent.PEER_CONNECT</li>
<li>ServiceEvent.PEER_DISCONNECT</li>
<li>ServiceEvent.RESULT</li>
</ul>
<p>The simplest way to use this service would be:</p>
<pre>    var service:MultiCastingService = new MultiCastingService();
    service.addEventListener(ServiceEvent.RESULT, onResult);
    service.addEventListener(ServiceEvent.CONNECTED, onStatusChange);
    service.addEventListener(ServiceEvent.PEER_CONNECT, onStatusChange);

    service.connect();

    private function onResult(e:ServiceEvent):void {
        if (e.what == "picture") {
            //do something with the bytes: e.body
        }
    }

    private function onStatusChange(e:ServiceEvent):void {
        if (e.type == ServiceEvent.PEER_CONNECT) {
            if (service.neighborCount &gt; 0) {
                //others are connected; send a String message
                service.post("this is my message");
            }
        }
    }
</pre>
<p>For the Android app I had to tweak the Spark List in order to make it works with both touch and click events. For the picture interaction I used a <a href="http://tinyurl.com/xdgesture" target="_blank">library</a> created by Tim Kukulski, a member of the Adobe XD team. This library makes it easy to interact with pictures by letting you use gestures like zoom, pan, or rotate.</p>
<p>The desktop application waits and responds to two kinds of messages: picture bytes and pictures transformations (rotation, zooming, or panning). Every time a picture is selected in the Android app, I grab its bytes and send them through the &#8220;wire&#8221;. When I transform a picture in the Android app, I grab the Matrix and send it to all the connected clients. The client applies the Matrix on the picture. And the rest is history :)</p>
<p>All in all it was pretty easy to put together these apps and I had a lot of fun while doing this. If I have the time, I will try to see if I can play the movies recorded with my Android by extending the current code.</p>
<h2>Getting the apps and source-code</h2>
<p>You can download the <a href="http://corlan.org/downloads/androidpictures/AndroidPicturesProjects.zip">source code</a> from here, install the desktop application from <a href="http://corlan.org/downloads/androidpictures/PicturesViewer.air">here</a>, and the Android application from <a href="http://corlan.org/downloads/androidpictures/AndroidPictures.apk">here</a>. If you want to run the Android application, you need to install Adobe AIR on your Android (more info <a href="http://labs.adobe.com/technologies/air2/android/" target="_blank">here</a>).</p>
<p>If you have ideas for more applications that take advantage of having AIR running on Android phones and desktops please let me know. If you create something interesting, I&#8217;d love to hear about. I already have another cool idea, this time more complex and even more fun!</p>
<p>Have fun with the Flash Platform on multiple screens!</p>
<div class="shr-publisher-2014"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/07/08/androidpictures-or-how-to-share-phone-pictures-with-desktops/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/6Rg4ls121d4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/07/08/androidpictures-or-how-to-share-phone-pictures-with-desktops/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/07/08/androidpictures-or-how-to-share-phone-pictures-with-desktops/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=androidpictures-or-how-to-share-phone-pictures-with-desktops</feedburner:origLink></item>
		<item>
		<title>Creating multi-screen apps for Android and desktop using AIR</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/qkXNHkLrHZg/</link>
		<comments>http://corlan.org/2010/07/02/creating-multi-screen-apps-for-android-and-desktop-using-air/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 14:04:52 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=2004</guid>
		<description><![CDATA[




			
				
			
		
Today, I finished a project I&#8217;ve been working since last week: a desktop MP3 Music Player that can be controlled by any number of Android phones. I built these apps using Adobe AIR and the Flex framework. Below you can watch a video with these apps in action, running on Motorola Droid, Nexus One, and [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/07/02/creating-multi-screen-apps-for-android-and-desktop-using-air/&title=Creating multi-screen apps for Android and desktop using AIR&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F07%2F02%2Fcreating-multi-screen-apps-for-android-and-desktop-using-air%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F07%2F02%2Fcreating-multi-screen-apps-for-android-and-desktop-using-air%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Today, I finished a project I&#8217;ve been working since last week: a desktop MP3 Music Player that can be controlled by any number of Android phones. I built these apps using Adobe AIR and the Flex framework. Below you can watch a video with these apps in action, running on Motorola Droid, Nexus One, and my laptop (you can watch <a href="http://vimeo.com/13033633" target="_blank">here</a> the video in a higher resolution).</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="300" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=13033633&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed type="application/x-shockwave-flash" width="400" height="300" src="http://vimeo.com/moogaloop.swf?clip_id=13033633&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>The communication between the remote controls (AIR apps running on Android phones) and  desktop player is done using the peer to peer features of AIR 2 and Flash Player 10.1. Basically if all the parties are connected to the same subnet and if the network allows broadcasting, then you can create a group and send messages to all the members without the need of Stratus or some other service/server.</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/07/desktop-player.png"><img class="aligncenter size-medium wp-image-2005" title="desktop-player" src="http://corlan.org/wp-content/uploads/2010/07/desktop-player-258x300.png" border="0" alt="" width="258" height="300" /></a></p>
<p>Actually, while working on this project I created a small class that enables you to quickly create clients who connect to a local network. Of course, this is only one way of connecting two or more clients. You can use sockets if you want, or one-to-one communication (peer2peer). But I think in both these cases you have to work more, because you have to manually manage all the parties involved. If you want to find out more about peer2peer features of the Flash Platform take a look at <a href="http://tv.adobe.com/watch/max-2009-develop/p2p-on-the-flash-platform-with-rtmfp" target="_blank">this MAX session</a> and read my fellow evangelist Tom Krcha&#8217;s <a href="http://www.flashrealtime.com/" target="_blank">blog</a>.</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/07/android-rc.png"><img class="aligncenter size-medium wp-image-2006" title="android-rc" src="http://corlan.org/wp-content/uploads/2010/07/android-rc-179x300.png" border="0" alt="" width="179" height="300" /></a></p>
<p>The Android app was more fun to build because I used the touch input mode along with click input. I enjoyed a lot tweaking James Ward&#8217;s <a href="http://www.jamesward.com/demos/MobileListSwipe2/srcview/" target="_blank">code</a> for scrolling a Flex List. Believe it or not, again I used Illustrator and Flash Catalyst a lot to create the skins or parts of them.</p>
<p>Until I have the time to put together an article explaining  how these apps were created, please enjoy the video and play with the apps: <a href="http://corlan.org/downloads/MusicPlayer.air">desktop file</a> and <a href="http://corlan.org/downloads/AndroidRemote.apk">APK file</a>. And from <a href="http://corlan.org/downloads/p2pandroid-desktop.zip">here</a> you can download an archive with the source code. If you need the Adobe AIR runtime or AIR SDK for Android, please sign in for the pre-release group <a href="http://labs.adobe.com/technologies/air2/android/" target="_blank">here</a>.</p>
<p>What do you think?</p>
<div class="shr-publisher-2004"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/07/02/creating-multi-screen-apps-for-android-and-desktop-using-air/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/qkXNHkLrHZg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/07/02/creating-multi-screen-apps-for-android-and-desktop-using-air/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/07/02/creating-multi-screen-apps-for-android-and-desktop-using-air/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=creating-multi-screen-apps-for-android-and-desktop-using-air</feedburner:origLink></item>
		<item>
		<title>Welcome to Hero – the next release of Flex SDK</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/4tRMBM5sve0/</link>
		<comments>http://corlan.org/2010/07/01/welcome-to-hero-the-next-release-of-flex-sdk/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 13:59:00 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1998</guid>
		<description><![CDATA[




			
				
			
		
Yesterday we announced Hero. This is the code-name for the next version of the Flex SDK. I think you&#8217;ll find the main themes for this release very interesting:

Multi-Screen Development: Allow developers to build applications that target the web, desktop or mobile devices using a single unified framework.
Spark Maturation: Polish and grow the Spark architecture by [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/07/01/welcome-to-hero-the-next-release-of-flex-sdk/&title=Welcome to Hero &#8211; the next release of Flex SDK&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F07%2F01%2Fwelcome-to-hero-the-next-release-of-flex-sdk%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F07%2F01%2Fwelcome-to-hero-the-next-release-of-flex-sdk%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Yesterday we announced Hero. This is the code-name for the next version of the Flex SDK. I think you&#8217;ll find the main themes for this release very interesting:</p>
<ul>
<li>Multi-Screen Development: Allow developers to build applications that target the web, desktop or mobile devices using a single unified framework.</li>
<li>Spark Maturation: Polish and grow the Spark architecture by adding new Spark components and capabilities.</li>
<li>Large-Application Development: Support developers building large applications by improving fundamental Flex infrastructure pieces.</li>
</ul>
<p>Among the big news is that both mobile and desktop needs will be served by the same core Flex framework (Hero). Previously, we said that Slider (the code name for the Flex Mobile Framework we announced at Max 2009) would be a separate framework from the Flex SDK. I think this is excellent news; having one framework to target both worlds (mobile and desktop) means that you, the developer, have to spent less time learning and coding.</p>
<p>You can read more about these themes <a href="http://blogs.adobe.com/flex/archives/2010/06/introducinghero.html" target="_blank">here</a>.</p>
<p>For now there are no public builds for Hero. We are working on this and pretty soon we will have public builds. Keep an eye on this <a href="http://opensource.adobe.com/wiki/display/flexsdk/Hero" target="_blank">site</a> for Hero white papers and builds.</p>
<div class="shr-publisher-1998"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/07/01/welcome-to-hero-the-next-release-of-flex-sdk/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/4tRMBM5sve0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/07/01/welcome-to-hero-the-next-release-of-flex-sdk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/07/01/welcome-to-hero-the-next-release-of-flex-sdk/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=welcome-to-hero-the-next-release-of-flex-sdk</feedburner:origLink></item>
		<item>
		<title>Two amazing Flash projects: Screenergy and Creaza</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/XQkkoOOgC3g/</link>
		<comments>http://corlan.org/2010/06/23/two-amazing-flash-projects-screenergy-and-creaza/#comments</comments>
		<pubDate>Wed, 23 Jun 2010 09:21:33 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Flash Platform]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1981</guid>
		<description><![CDATA[




			
				
			
		
If you haven&#8217;t seen these two projects, then please keep reading. I&#8217;m sure even if you are familiar with all kinds of cool rich Internet apps these two apps will surprise you. And to tell you the truth, I was surprised too. It seems that every now and then some cool projects pop up and [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/06/23/two-amazing-flash-projects-screenergy-and-creaza/&title=Two amazing Flash projects: Screenergy and Creaza&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F06%2F23%2Ftwo-amazing-flash-projects-screenergy-and-creaza%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F06%2F23%2Ftwo-amazing-flash-projects-screenergy-and-creaza%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>If you haven&#8217;t seen these two projects, then please keep reading. I&#8217;m sure even if you are familiar with all kinds of cool rich Internet apps these two apps will surprise you. And to tell you the truth, I was surprised too. It seems that every now and then some cool projects pop up and they manage to move what is possible with the Flash Platform to a whole new level.</p>
<p>Enough talking, let&#8217;s start with the first project. <a href="http://screenergy.com/#/overview.html" target="_blank">Screenergy.com</a> is a multi-touch 46&#8243; full HD table with object tracking capabilities. Well, these specs are cool but not something to amaze you. Yet! They used this cool hardware as the platform to run AIR applications that allow people of any age and background to interact visually with a system that handles and displays loads of data. Basically, the system can recognize a specialized card you place on the table and display the information related to that card. You can move the card on the screen, and you can expand and change settings. Here are some pictures to help you better grasp the amazing interactivity that Screenergy provides:</p>
<p style="text-align: center;"><img class="size-medium wp-image-1983   aligncenter" title="Screenergy" src="http://corlan.org/wp-content/uploads/2010/06/screenergy_1-300x175.jpg" border="0" alt="" width="300" height="175" /></p>
<p style="text-align: center;">
<div>
<p style="text-align: center;"><a href="http://corlan.org/wp-content/uploads/2010/06/screenergy_3.jpg"><img class="alignnone size-thumbnail wp-image-1984" title="Screenergy" src="http://corlan.org/wp-content/uploads/2010/06/screenergy_3-150x150.jpg" border="0" alt="" width="150" height="150" /></a> <a href="http://corlan.org/wp-content/uploads/2010/06/screenergy_4.jpg"><img class="alignnone size-thumbnail wp-image-1985" title="Screenergy" src="http://corlan.org/wp-content/uploads/2010/06/screenergy_4-150x150.jpg" border="0" alt="" width="150" height="150" /></a> <a href="http://corlan.org/wp-content/uploads/2010/06/screenergy_5.jpg"><img class="alignnone size-thumbnail wp-image-1986" title="Screenergy" src="http://corlan.org/wp-content/uploads/2010/06/screenergy_5-150x150.jpg" border="0" alt="" width="150" height="150" /></a></p>
</div>
<p>This project was built for the Global Climate conference in Copenhagen (2009). And the visitors and VIPs were able to visualize the impact that different changes have on the climate. <a href="http://101-solutions.org/swf/InteractiveOnline.html" target="_blank">Here</a> you can get a taste of the application and here is a video with the table in action:</p>
<div style="text-align: center;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="300" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=12616681&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed type="application/x-shockwave-flash" width="400" height="300" src="http://vimeo.com/moogaloop.swf?clip_id=12616681&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></div>
<p>I knew about this project from the beginning because the people who built it approached me back in October 2009. They told me &#8220;we want to build an application for a touch table using AIR for the UI, and the client is one of the organizations behind the Copenhagen&#8217;s Climate Change conference. We have about a month to do it! &#8220;. Then we talked about AIR 2 features (at that time it was in private beta) and how they could leverage AIR 2 features for their project. And then, before Christmas, I received an email from them telling me that the project was delivered on time and it was a success.</p>
<p>The second project, <a href="http://www.creaza.com/frontpage" target="_blank">Creaza.com</a>, is delivered as a web application using Flash Player. It is a suite of four programs: a mind-mapping tool, a movie editor, a sound editor, and an online comic tool for creating cartoons/digital stories. Funny,  I know the guys behind this project too :) I had the pleasure to meet them back in 2007 during a user interview around Flex Builder 2 at that time.</p>
<div><a href="http://corlan.org/wp-content/uploads/2010/06/creaza_1.jpg"></a></div>
<p style="text-align: center;"><img class="aligncenter size-medium wp-image-1987" title="Creaza" src="http://corlan.org/wp-content/uploads/2010/06/creaza_1-300x206.jpg" border="0" alt="" width="300" height="206" /></p>
<p>For me the most amazing product from this suite is MovieEditor. It is one thing to play video in the browser and a totally different thing to be able to create a movie inside the browser using a web application that is pretty close to desktop video editors in terms of features and performance. You can use this timeline-based video editor to create movies  complete with professional-looking titles, transitions, effects, animation, music, and narration. You can test this app <a href="http://www.creaza.com/static/creaza/preview/index.html" target="_blank">here</a>.</p>
<div><a href="http://corlan.org/wp-content/uploads/2010/06/creaza_2.jpg"></a></div>
<p style="text-align: center;"><img class="size-medium wp-image-1988  aligncenter" title="Creaza" src="http://corlan.org/wp-content/uploads/2010/06/creaza_2-300x185.jpg" border="0" alt="" width="300" height="185" /></p>
<p>I think these two projects are not at all two lonely rain drops lost in an ocean. I strongly believe that this is the natural result of the maturity and power the Flash Platform has achieved. The Flash Platform truly makes easy things easy, and hard things possible. There are more than 3 million Flash developers according to Evans Data, and many of these developer started with the Platform in the past two years. There are tons of libraries, frameworks, and tools to pick from (both commercial and open-source). There are many companies and agencies with a lot of experience in building rich Internet applications.</p>
<p>In a nutshell, I&#8217;m seeing an ecosystem that is growing and innovating faster than ever. Thus, I&#8217;m sure that many more cool projects will cross my path and I&#8217;d be happy to talk about them. And remember, these two projects are not just a proof of concept; these are fully functional projects that make money. The companies who built them are not huge corporations &#8211; quite the contrary. But what they may lack in terms of money they make up in imagination and a belief that everything is possible!</p>
<p>What do you think?</p>
<div class="shr-publisher-1981"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/06/23/two-amazing-flash-projects-screenergy-and-creaza/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/XQkkoOOgC3g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/06/23/two-amazing-flash-projects-screenergy-and-creaza/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/06/23/two-amazing-flash-projects-screenergy-and-creaza/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=two-amazing-flash-projects-screenergy-and-creaza</feedburner:origLink></item>
		<item>
		<title>Flash Builder’s Lost Features: Call Hierarchy</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/xKnC-SvMaTQ/</link>
		<comments>http://corlan.org/2010/06/18/flash-builders-lost-features-call-hierarchy/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 09:53:05 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Flash Builder]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1971</guid>
		<description><![CDATA[




			
				
			
		
Last week I had the pleasure to present to the first edition of gotoAndSki() conference, up north in Norway. During one of my sessions people said that it&#8217;d be a great thing if Adobe could present the Flash Builder new features in such a way that it makes easier to learn them. They suggested instead [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/06/18/flash-builders-lost-features-call-hierarchy/&title=Flash Builder&#8217;s Lost Features: Call Hierarchy&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F06%2F18%2Fflash-builders-lost-features-call-hierarchy%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F06%2F18%2Fflash-builders-lost-features-call-hierarchy%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Last week I had the pleasure to present to the first edition of <a href="http://www.gotoandski.com/">gotoAndSki()</a> conference, up north in Norway. During one of my sessions people said that it&#8217;d be a great thing if Adobe could present the Flash Builder new features in such a way that it makes easier to learn them. They suggested instead of just throwing big PDFs to the community, we could also have blog posts tackling one feature at a time. I think this makes sense; we are all too busy with current and upcoming projects to find the time to go through manuals.</p>
<p>So here I come and I start today a series of articles called Flash Builder&#8217;s Lost Features. Today I&#8217;ll present Call Hierarchy command. This command makes it easy to find all the places where a particular property/variable/function/method is used in your project. It works for ActionScript or Flex projects.</p>
<p>To use this feature, right-click the variable or method you are interested in and select Open Call Hierarchy.</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/06/call-hierarchy1.jpg"><img class="aligncenter size-medium wp-image-1973" title="call-hierarchy1" src="http://corlan.org/wp-content/uploads/2010/06/call-hierarchy1-300x271.jpg" alt="" width="300" height="271" /></a></p>
<p>When you do this, you should see in Flash Builder a new view (named Call Hierarchy) with all the occurrences of what you&#8217;ve selected. If you double-click an entry, Flash Builder will open the file where that entry can be found and you can inspect the code. Also, you can extend a node to see the call stack trace. And all of this can be done without having to run the project.</p>
<p><a href="http://corlan.org/wp-content/uploads/2010/06/call-hierarchy2.jpg"><img class="aligncenter size-medium wp-image-1974" title="call-hierarchy2" src="http://corlan.org/wp-content/uploads/2010/06/call-hierarchy2-300x92.jpg" alt="" width="300" height="92" /></a></p>
<p>This is it for now. Like I said, it is a small and simple to use feature, but it is pretty powerful. In the next episode I will talk about Flash Builder&#8217;s Profiler.</p>
<div class="shr-publisher-1971"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/06/18/flash-builders-lost-features-call-hierarchy/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/xKnC-SvMaTQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/06/18/flash-builders-lost-features-call-hierarchy/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/06/18/flash-builders-lost-features-call-hierarchy/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=flash-builders-lost-features-call-hierarchy</feedburner:origLink></item>
		<item>
		<title>Flash Coffee Bucharest</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/xAhMBOpKmVE/</link>
		<comments>http://corlan.org/2010/06/17/flash-coffee-bucharest/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 08:33:54 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Conferences]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1963</guid>
		<description><![CDATA[




			
				
			
		
I know it has been way too hot lately, especially here in Bucharest. I have good news. First, next week the weather is expected to be cooler.  And second, I plan to host a Flash Coffee Meetup in Bucharest! The event will take place next Tuesday (June 22nd) at Grand Cafe Galleron (near La Mama [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/06/17/flash-coffee-bucharest/&title=Flash Coffee Bucharest&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F06%2F17%2Fflash-coffee-bucharest%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F06%2F17%2Fflash-coffee-bucharest%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>I know it has been way too hot lately, especially here in Bucharest. I have good news. First, next week the weather is expected to be cooler.  And second, I plan to host a Flash Coffee Meetup in Bucharest! The event will take place next Tuesday (June 22nd) at Grand Cafe Galleron (near La Mama restaurant, P-ta Romana) starting at 5PM.</p>
<p>There are only 15 tickets so hurry up and use this <a href="http://bucharest.eventbrite.com/">link</a> to register. I&#8217;ll pay for the coffee and bring an Android phone with Flash Player 10.1 and Adobe AIR installed on it. Thus we can enjoy a good cup of coffee on a cold day (something that we&#8217;ll pretty soon miss :D) and talk about the latest Flash Platform and mobile device news.</p>
<p><img class="aligncenter size-full wp-image-1964" title="flash coffee bucharest" src="http://corlan.org/wp-content/uploads/2010/06/flashcoffee.jpg" alt="" width="590" height="155" /></p>
<p>You can register <a href="http://bucharest.eventbrite.com/">here</a>. See you next Tuesday.</p>
<div class="shr-publisher-1963"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/06/17/flash-coffee-bucharest/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/xAhMBOpKmVE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/06/17/flash-coffee-bucharest/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/06/17/flash-coffee-bucharest/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=flash-coffee-bucharest</feedburner:origLink></item>
		<item>
		<title>Adobe MAX Awards 2010</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/Dmp62AXhMlw/</link>
		<comments>http://corlan.org/2010/06/15/adobe-max-awards-2010/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 07:45:50 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Conferences]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1957</guid>
		<description><![CDATA[




			
				
			
		
The Adobe MAX Awards 2010 competition is open (the deadline for project submission is August 13th &#8211; hope you are not superstitious :D). This year&#8217;s categories are:

Advertising and Branding
Digital Publishing
Enterprise/Government RIAs
Entertainment
Multiscreen
Social Computing

Good luck!
]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/06/15/adobe-max-awards-2010/&title=Adobe MAX Awards 2010&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F06%2F15%2Fadobe-max-awards-2010%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F06%2F15%2Fadobe-max-awards-2010%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>The Adobe <a href="http://max.adobe.com/awards/" target="_blank">MAX Awards 2010</a> competition is open (the deadline for project submission is August 13th &#8211; hope you are not superstitious :D). This year&#8217;s categories are:</p>
<ul>
<li>Advertising and Branding</li>
<li>Digital Publishing</li>
<li>Enterprise/Government RIAs</li>
<li>Entertainment</li>
<li>Multiscreen</li>
<li>Social Computing</li>
</ul>
<p>Good luck!</p>
<div class="shr-publisher-1957"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/06/15/adobe-max-awards-2010/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/Dmp62AXhMlw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/06/15/adobe-max-awards-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/06/15/adobe-max-awards-2010/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=adobe-max-awards-2010</feedburner:origLink></item>
		<item>
		<title>Adobe Flash Platform Summit 2010</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/puFGxJBdJu4/</link>
		<comments>http://corlan.org/2010/06/14/adobe-flash-platform-summit-2010/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 10:43:29 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Conferences]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1953</guid>
		<description><![CDATA[




			
				
			
		
This August (25th &#8211; 26th) if you live in India and you work in the IT field then you really should consider attending Adobe Flash Platform Summit 2010 in Bangalore, India.

This is a two day event, and more than 2000 people are expected with tens of sessions and international speakers. You can read more here [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/06/14/adobe-flash-platform-summit-2010/&title=Adobe Flash Platform Summit 2010&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F06%2F14%2Fadobe-flash-platform-summit-2010%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F06%2F14%2Fadobe-flash-platform-summit-2010%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>This August (25th &#8211; 26th) if you live in India and you work in the IT field then you really should consider attending Adobe Flash Platform Summit 2010 in Bangalore, India.</p>
<p><img class="aligncenter size-medium wp-image-1954" title="asummit2010" src="http://corlan.org/wp-content/uploads/2010/06/asummit2010-300x127.jpg" alt="" width="300" height="127" /></p>
<p>This is a two day event, and more than 2000 people are expected with tens of sessions and international speakers. You can read more <a href="http://www.developermarch.com/adobesummit/" target="_blank">here</a> and you can register <a href="http://www.developermarch.com/adobesummit/registration.html">here</a> (you can save 60% if you register before June 25th). If you want to propose a session then hurry up because the window is closing on June 21st.</p>
<div class="shr-publisher-1953"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/06/14/adobe-flash-platform-summit-2010/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/puFGxJBdJu4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/06/14/adobe-flash-platform-summit-2010/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/06/14/adobe-flash-platform-summit-2010/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=adobe-flash-platform-summit-2010</feedburner:origLink></item>
		<item>
		<title>Going Multi-Screen with the Flash Platform Webinar</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/1JQ7vGGzkxw/</link>
		<comments>http://corlan.org/2010/06/09/going-multi-screen-with-the-flash-platform-webinar/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 19:40:53 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Others]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1947</guid>
		<description><![CDATA[




			
				
			
		
It seems this summer that webinars are highly fashionable. The App in a Week European webinar hasn&#8217;t finished yet, and we&#8217;ve announced another one: Going Multi-Screen with the Flash Platform. The webinars will take place between June 22nd &#8211; 24th and you can register here.
I guess after attending these webinars you should be ready to [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/06/09/going-multi-screen-with-the-flash-platform-webinar/&title=Going Multi-Screen with the Flash Platform Webinar&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F06%2F09%2Fgoing-multi-screen-with-the-flash-platform-webinar%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F06%2F09%2Fgoing-multi-screen-with-the-flash-platform-webinar%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>It seems this summer that webinars are highly fashionable. The App in a Week European webinar hasn&#8217;t finished yet, and we&#8217;ve announced another one: Going Multi-Screen with the Flash Platform. The webinars will take place between June 22nd &#8211; 24th and you can register <a href="http://www.adobe.com/go/multiscreen">here</a>.</p>
<p>I guess after attending these webinars you should be ready to create multi-screen applications when Flash Player 10.1 and Adobe AIR will be available for the Android platform (now they are still in beta).</p>
<p>This is the complete schedule:</p>
<ul>
<li>Tuesday, June 22, 9AM – 10AM Pacific Time &#8211; Best practices in optimizing web content for Flash Player 10.1</li>
<li>Tuesday, June 22, 1PM – 2PM Pacific Time &#8211; The quickest way to build cross-platform apps with AIR 2</li>
<li>Wednesday, June 23, 9AM – 10AM Pacific Time &#8211; Rich Internet App development with Flash Builder 4 for Flash Player 10.1 and AIR 2</li>
<li>Thursday, June 24 9AM – 10AM Pacific Time &#8211; Multi-screen web content development with Flash Pro CS5</li>
</ul>
<p>Enjoy!</p>
<div class="shr-publisher-1947"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/06/09/going-multi-screen-with-the-flash-platform-webinar/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/1JQ7vGGzkxw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/06/09/going-multi-screen-with-the-flash-platform-webinar/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/06/09/going-multi-screen-with-the-flash-platform-webinar/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=going-multi-screen-with-the-flash-platform-webinar</feedburner:origLink></item>
		<item>
		<title>Flex and PHP webinar goodies</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/UmE1HGWQ_1g/</link>
		<comments>http://corlan.org/2010/06/07/flex-and-php-webinar-goodies/#comments</comments>
		<pubDate>Mon, 07 Jun 2010 20:10:57 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Presentations]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1936</guid>
		<description><![CDATA[




			
				
			
		
As I promised at the end of my webinar here I come with the projects I used:

The starting project created using Flash Catalyst
The finished project (Flex and PHP project)
PSD file

You can use the Import &#62; Flash Builder &#62; Flex project wizard to import these two projects into Flash Builder. However, to make the second project [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/06/07/flex-and-php-webinar-goodies/&title=Flex and PHP webinar goodies&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F06%2F07%2Fflex-and-php-webinar-goodies%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F06%2F07%2Fflex-and-php-webinar-goodies%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>As I promised at the end of my webinar here I come with the projects I used:</p>
<ul>
<li>The starting <a href="http://corlan.org/downloads/appinaweek/EVA_design.fxp">project</a> created using Flash Catalyst</li>
<li>The finished <a href="http://corlan.org/downloads/appinaweek/EVA_final.fxp">project</a> (Flex and PHP project)</li>
<li>PSD <a href="http://corlan.org/downloads/appinaweek/EVA_design.psd">file</a></li>
</ul>
<p>You can use the Import &gt; Flash Builder &gt; Flex project wizard to import these two projects into Flash Builder. However, to make the second project work, you need to copy the PHP files from inside the project (you&#8217;ll find a folder named eva_services with a bunch of files) to the root of your PHP server. Next you have to create the database (there is an SQL dump inside the same folder) and change the connection credentials from eva_credentials/db.php to match your local settings). Actually you can read more about this in my <a href="http://corlan.org/debugging-flex-and-php/">article</a> on Debugging Flex and PHP projects.</p>
<p>I know that I squeezed quite a lot in my webinar and I had to move quickly between the topics. But you don&#8217;t have to worry because you&#8217;ll find articles and screencasts below that go into great detail on all the topics I covered:</p>
<ul>
<li>Setting up XDebug and debugging Flex and PHP projects <a href="http://corlan.org/debugging-flex-and-php/">here</a></li>
<li>Working with Doctrine, Zend Framework, and Flex <a href="http://corlan.org/2010/05/05/working-with-doctrine-zend-framework-and-flex/">here</a></li>
<li>Working with Flash Builder&#8217;s DCD features on PHP projects <a href="http://www.adobe.com/devnet/flex/articles/flex_php.html">here</a></li>
<li>You&#8217;ll find many Flex and PHP articles and videos on the <a href="http://www.adobe.com/devnet/flex/flex_php.html">Flex and PHP  section</a> of Adobe Developer Connection site, <a href="http://www.adobe.com/devnet/flex/flex_php.html"></a></li>
<li>If you want to read more about remoting and AMF using Zend Framework or AMFPHP here are two articles I wrote awhile ago: <a href="http://corlan.org/2008/11/13/flex-and-php-remoting-with-zend-amf/">Zend Framework</a> and <a href="http://corlan.org/2008/10/10/flex-and-php-remoting-with-amfphp/">AMFPHP</a></li>
<li>Data Paging using DCD features <a href="http://corlan.org/2009/07/01/data-paging-with-flex-and-php-in-flash-builder/">here</a></li>
</ul>
<p>Finally, the recordings for the webinars:</p>
<ul>
<li><a href="http://my.adobe.acrobat.com/p90445619/ ">Erase the Designer to Developer gap: Adding interactions to your design</a> (Serge Jespers&#8217;s session)</li>
<li><a href="http://my.adobe.acrobat.com/p66013176/">Connecting a Flex app to PHP services</a> (my session)</li>
<li><a href="http://my.adobe.acrobat.com/p20174257/">Connecting a web application to a J2EE backend using Flash Builder 4 </a>(Michael Chaize&#8217;s session)</li>
<li><a href="http://my.adobe.acrobat.com/p49752948/">Working with Flash CS5 components in your Flash Builder 4 project</a> (Mike Jones&#8217;s session)</li>
<li><a href="http://my.adobe.acrobat.com/p93914495/">Going multi-user with P2P in Flash Player 10.1</a> (Tom Krcha&#8217;s session)</li>
<li><a href="http://my.adobe.acrobat.com/p53039407/">Developing multi-user applications with  LiveCycle services</a> (Tom Krcha&#8217;s session)</li>
<li><a href="http://my.adobe.acrobat.com/p97751544/ ">Bringing web Applications to the desktop with AIR 2</a> (Piotr Walczyscyn&#8217;s session)</li>
<li><a href="http://my.adobe.acrobat.com/p24983267/">Code once and run on multiple mobile devices</a> (Mark Doherty&#8217;s session)</li>
<li><a href="http://my.adobe.acrobat.com/p57074073/">Rapidly build, deploy, and maintain Internet apps with ColdFusion</a> (Terry Ryan&#8217;s session)</li>
</ul>
<p>Again, I want to thank all of you who took the time to attend my session. Until the next time, Ciao!</p>
<div class="shr-publisher-1936"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/06/07/flex-and-php-webinar-goodies/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/UmE1HGWQ_1g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/06/07/flex-and-php-webinar-goodies/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/06/07/flex-and-php-webinar-goodies/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=flex-and-php-webinar-goodies</feedburner:origLink></item>
		<item>
		<title>Test your AIR apps on an Android phone</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/g8HwQh7Ey4w/</link>
		<comments>http://corlan.org/2010/05/31/test-your-air-apps-on-an-android-phone/#comments</comments>
		<pubDate>Mon, 31 May 2010 09:15:07 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1930</guid>
		<description><![CDATA[




			
				
			
		
I realized that for us (Europeans) it is a little bit harder to get our hands on a Nexus One or Droid phone. So, if you have created an AIR app for Android and you don&#8217;t have a device to test it on we can meet at one of the next events I&#8217;m doing and [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/05/31/test-your-air-apps-on-an-android-phone/&title=Test your AIR apps on an Android phone&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F31%2Ftest-your-air-apps-on-an-android-phone%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F05%2F31%2Ftest-your-air-apps-on-an-android-phone%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>I realized that for us (Europeans) it is a little bit harder to get our hands on a Nexus One or Droid phone. So, if you have created an AIR app for Android and you don&#8217;t have a device to test it on we can meet at one of the next events I&#8217;m doing and I will let you do the testing. Maybe we can shoot a video too :)</p>
<p>For now, my schedule looks like this:</p>
<ul>
<li>June 2nd I&#8217;ll be in Cluj-Napoca Romania  attending a <a href="http://flexcluj.eventbrite.com/" target="_blank">Flex Camp</a></li>
<li>June 3rd &#8211; 5th Timisoara Romania, attending and speaking at <a href="http://www.drupalcamp.ro" target="_blank">Drupal Camp</a></li>
<li>June 10th-12th Norway attending <a href="http://www.gotoandski.com/" target="_blank">gotoAndSki()</a></li>
</ul>
<p>If you live in Bucharest, just send me an email and we will figure out a date depending on when I&#8217;m not travelling.</p>
<p>Looking forward to seeing what you build :)</p>
<div class="shr-publisher-1930"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/05/31/test-your-air-apps-on-an-android-phone/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/g8HwQh7Ey4w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/05/31/test-your-air-apps-on-an-android-phone/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/05/31/test-your-air-apps-on-an-android-phone/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=test-your-air-apps-on-an-android-phone</feedburner:origLink></item>
		<item>
		<title>Open Source Media Framework 1.0 is out</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/hug3sR95zag/</link>
		<comments>http://corlan.org/2010/05/30/open-source-media-framework-1-0-is-out/#comments</comments>
		<pubDate>Sun, 30 May 2010 07:23:08 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Others]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1927</guid>
		<description><![CDATA[




			
				
			
		
The first release of OSMF, 1.0 is out. This is great news for both developers and publishers. Using the components from OSMF you can build quickly high quality and fully featured video players. And if you think about this, it totally make sense. I mean if you are a publisher your main expertise is to [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/05/30/open-source-media-framework-1-0-is-out/&title=Open Source Media Framework 1.0 is out&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F30%2Fopen-source-media-framework-1-0-is-out%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F05%2F30%2Fopen-source-media-framework-1-0-is-out%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>The first release of OSMF, 1.0 is out. This is great news for both developers and publishers. Using the components from OSMF you can build quickly high quality and fully featured video players. And if you think about this, it totally make sense. I mean if you are a publisher your main expertise is to create/distribute/monetize the content and not to create advanced video players. And if you are a developer then you get an excellent start using components that were already tested and supports the latest advancements from the Flash Platform (Flash Player 10.1, Flash Access 2.0, HTTP Dynamic Streaming).</p>
<p>OSMF gives you the blocks you need to build a modern and powerful video player. What if you just want an out of the box player? Well, you have to take a look at Strobe Media Playback then. This is a compiled SWF that gives you a video player created using the OSMF.</p>
<p><img class="aligncenter size-full wp-image-1928" title="Strobe player" src="http://corlan.org/wp-content/uploads/2010/05/image001.jpg" alt="" width="434" height="269" /></p>
<p>I just want to add one more thing: OSMF was developed by many parties, not only by Adobe. Others submitted plug-ins and code. I know my friends from Kaltura are one of them, but other big names like ESPN, Akamai, Brightcove.</p>
<p>You can find more <a href="http://www.osmf.org/" target="_blank">here</a>.</p>
<div class="shr-publisher-1927"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/05/30/open-source-media-framework-1-0-is-out/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/hug3sR95zag" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/05/30/open-source-media-framework-1-0-is-out/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/05/30/open-source-media-framework-1-0-is-out/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=open-source-media-framework-1-0-is-out</feedburner:origLink></item>
		<item>
		<title>Webinar: App in a Week</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/-55y8xQSFzQ/</link>
		<comments>http://corlan.org/2010/05/26/webinar-app-in-a-week/#comments</comments>
		<pubDate>Wed, 26 May 2010 10:18:51 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Presentations]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1919</guid>
		<description><![CDATA[




			
				
			
		
The entire European platform evangelism team worked hard to create great content for a webinar called App in a Week (June 7th-10th). What is it all about? In short: We will show you how you can create applications using various
techniques with the help of the Flash Platform. Basically you will see different tools at work [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/05/26/webinar-app-in-a-week/&title=Webinar: App in a Week&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F26%2Fwebinar-app-in-a-week%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F05%2F26%2Fwebinar-app-in-a-week%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>The entire European platform evangelism team worked hard to create great content for a webinar called App in a Week (June 7th-10th). What is it all about? In short: We will show you how you can create applications using various<br />
techniques with the help of the Flash Platform. Basically you will see different tools at work (Flash Professional, Flash Catalyst, Flash Builder, Photoshop), different approaches (Flex, ActionScript, desktop, mobile or web apps) and different back-end technologies (PHP or Java).</p>
<p>Long answer: it&#8217;s really too long, so better <a href="http://www.adobe.com/uk/appinaweek/">sign up</a> and join us. I&#8217;m sure you&#8217;ll find new things. Here is the complete schedule:</p>
<ul>
<li>June 7th – 12:00 – 13:00 GMT Erase the Designer to Developer gap: Adding interactions to your design with <a href="http://webkitchen.be/">Serge Jespers</a></li>
<li>June 7th – 15:00 – 16:00 GMT Connecting your design to PHP services with <a href="http://corlan.org">Mihai Corlan</a></li>
<li>June 8th – 12:00 – 13:00 GMT Connecting a web application to a J2EE backend using Flash Builder 4 with <a href="http://www.riagora.com/">Michael Chaize</a></li>
<li>June 8th – 15:00 – 16:00 GMT Working with Flash CS5 components in your Flash Builder 4 project with <a href="http://blog.flashgen.com/">Mike Jones</a></li>
<li>June 9th – 12:00 – 13:00 GMT Going multi-user with P2P in Flash Player 10.1 with <a href="http://www.flashrealtime.com/">Tom Krcha</a></li>
<li>June 9th – 15:00 – 16:00 GMT Developing multi-user applications with LiveCycle services with <a href="http://www.flashrealtime.com/">Tom Krcha</a></li>
<li>June 10th – 12:00 – 13:00 GMT Bringing web Applications to the desktop with AIR 2.0 with <a href="http://www.riaspace.net/">Piotr Walczyscyn</a></li>
<li>June 10th – 15:00 – 16:00 GMT Code once and run on multiple mobile devices with <a href="http://www.flashmobileblog.com/">Mark Doherty</a></li>
</ul>
<p>As you can see we set up the event to work well for Europeans :) You can register <a href="http://www.adobe.com/uk/appinaweek/">here</a>!</p>
<div class="shr-publisher-1919"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/05/26/webinar-app-in-a-week/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/-55y8xQSFzQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/05/26/webinar-app-in-a-week/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/05/26/webinar-app-in-a-week/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=webinar-app-in-a-week</feedburner:origLink></item>
		<item>
		<title>Flash Player and Google TV</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/ofm7FvebJrY/</link>
		<comments>http://corlan.org/2010/05/21/flash-player-and-google-tv/#comments</comments>
		<pubDate>Fri, 21 May 2010 20:14:57 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[Flash Player]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1908</guid>
		<description><![CDATA[




			
				
			
		
If you watch the news or what&#8217;s happening at Google I/O 2010 chances are that Google TV is not a novelty anymore. However you may not know that Google TV uses Flash Player 10.1 (Google&#8217;s browser, Chrome, integrates Flash Player). This is something I know for sure I want. Being able to watch YouTube videos [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/05/21/flash-player-and-google-tv/&title=Flash Player and Google TV&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F21%2Fflash-player-and-google-tv%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F05%2F21%2Fflash-player-and-google-tv%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>If you watch the news or what&#8217;s happening at Google I/O 2010 chances are that Google TV is not a novelty anymore. However you may not know that Google TV uses Flash Player 10.1 (Google&#8217;s browser, Chrome, integrates Flash Player). This is something I know for sure I want. Being able to watch YouTube videos on my TV with my whole family, instead of huddling around a small computer screen, is really nice.</p>
<p>On the other hand, I can&#8217;t believe how fast the time flies and how fast the technology evolves and morphs these days. One year ago I was in Berlin talking with journalists for the first time about Digital Home, where the TV sets can handle both the web and regular TV shows.</p>
<p>Here you can see a video with Google TV running Flash content:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="256" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="FlashVars" value="fileID=6606&amp;context=76&amp;embeded=true&amp;environment=production" /><param name="src" value="http://images.tv.adobe.com/swf/player.swf" /><param name="flashvars" value="fileID=6606&amp;context=76&amp;embeded=true&amp;environment=production" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="256" src="http://images.tv.adobe.com/swf/player.swf" flashvars="fileID=6606&amp;context=76&amp;embeded=true&amp;environment=production" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div class="shr-publisher-1908"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/05/21/flash-player-and-google-tv/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/ofm7FvebJrY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/05/21/flash-player-and-google-tv/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/05/21/flash-player-and-google-tv/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=flash-player-and-google-tv</feedburner:origLink></item>
		<item>
		<title>Get AIR for Android and play with it</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/y125q_V5wC0/</link>
		<comments>http://corlan.org/2010/05/20/get-air-for-android-and-play-with-it/#comments</comments>
		<pubDate>Thu, 20 May 2010 18:37:00 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1902</guid>
		<description><![CDATA[




			
				
			
		
Today, at Google I/O 2010 we have announced a public beta of the Adobe AIR for Android. This means you can sign in for getting the bits and if you have a Google Nexus One phone you can install the runtime and then test the existent AIR apps for Android or create new ones.

So this [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/05/20/get-air-for-android-and-play-with-it/&title=Get AIR for Android and play with it&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F20%2Fget-air-for-android-and-play-with-it%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F05%2F20%2Fget-air-for-android-and-play-with-it%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Today, at Google I/O 2010 we have announced a public beta of the Adobe AIR for Android. This means you can sign in for getting the bits and if you have a Google Nexus One phone you can install the runtime and then test the existent AIR apps for Android or create new ones.</p>
<p><img class="aligncenter size-full wp-image-1903" title="asplitter" src="http://corlan.org/wp-content/uploads/2010/05/asplitter.jpg" alt="" width="500" height="360" /></p>
<p>So this makes the perfect moment for sharing my AIR app for Android that will come handy every time you have a dinner with others and want to split the bill. So grab the APK file from <a href="http://corlan.org/downloads/aTabSplitter.apk">here</a>,  make sure you have the Android SDK on your machine and the phone is connected to the computer through the USB cable, and then run this command in console :</p>
<blockquote><p>adb install -r aTabSplitter.apk</p></blockquote>
<p>If you don&#8217;t like command line, then you can use Serge Jespers AIR app for packaging AIR apps as native installers including APK files for Android. Check his blog post <a href="http://www.webkitchen.be/package-assistant-pro/" target="_blank">here</a>.</p>
<p>You can get the AIR for Android bits from <a href="http://labs.adobe.com/technologies/air2/android/" target="_blank">here</a> (and find more about developing for Android with Adobe AIR).</p>
<p>If you play with my app and you have feedback, please drop a comment!</p>
<div class="shr-publisher-1902"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/05/20/get-air-for-android-and-play-with-it/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/y125q_V5wC0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/05/20/get-air-for-android-and-play-with-it/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/05/20/get-air-for-android-and-play-with-it/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=get-air-for-android-and-play-with-it</feedburner:origLink></item>
		<item>
		<title>Building Android apps with Adobe AIR</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/YzN81esUQuc/</link>
		<comments>http://corlan.org/2010/05/19/building-android-apps-with-adobe-air/#comments</comments>
		<pubDate>Wed, 19 May 2010 19:40:11 +0000</pubDate>
		<dc:creator>Mihai Corlan</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://corlan.org/?p=1895</guid>
		<description><![CDATA[




			
				
			
		
Last week I created my first ever mobile application. It is an AIR app for Android. The app is called aTabSplitter because ahh, it just helps you to split a restaurant bill between many people. Here are some screenshots with the two screens of the app:

Developing this small application was quite entertaining. But it teach [...]]]></description>
			<content:encoded><![CDATA[<div id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/05/19/building-android-apps-with-adobe-air/&title=Building Android apps with Adobe AIR&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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%2F19%2Fbuilding-android-apps-with-adobe-air%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcorlan.org%2F2010%2F05%2F19%2Fbuilding-android-apps-with-adobe-air%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Last week I created my first ever mobile application. It is an AIR app for Android. The app is called aTabSplitter because ahh, it just helps you to split a restaurant bill between many people. Here are some screenshots with the two screens of the app:</p>
<p><img class="aligncenter size-full wp-image-1896" title="atabsplit" src="http://corlan.org/wp-content/uploads/2010/05/atabsplit.jpg" alt="" width="500" height="381" /></p>
<p>Developing this small application was quite entertaining. But it teach me a few lessons too:</p>
<ul>
<li>You know the old saying &#8220;premature optimization is the root of all evil&#8221;. This is true for mobile apps too. You never know if some framework or workflow will do the job until you actually try. In my case, the common sense was telling me that Flex 4 framework being a desktop framework is to heavy for the mobile world. After trying it, I think actually it works quite good for me. Your mileage can vary.</li>
<li>Developing for mobile is not easy at all. I spent almost my entire professional life building web applications for desktops. Doing mobile apps after this is like trying to create jewels miniatures with the skills of a mine worker. You need a different mind set; you need to acquire new skills.</li>
<li>It is highly educational watching people using your app. Because of the touch-input nature of the mobile apps and the personal experience each user carries forward from previous devices/apps, you will certainly notice some interesting behaviors. With my app, a friend tried to remove a person (on the first screen) by throwing him outside of the screen. Needless to say that I didn&#8217;t think of this workflow, but it gave me an idea on how to improve the app.</li>
</ul>
<p>Finally, this week I had the time to clean up the UI and code a little bit, and put together a video (the making-of type of video). Here is the video (you can watch the video in higher resolution <a href="http://vimeo.com/11876822" target="_new">here</a>):</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="300" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=11876822&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed type="application/x-shockwave-flash" width="400" height="300" src="http://vimeo.com/moogaloop.swf?clip_id=11876822&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>If you want to have a look at the code (although I warn you it is not production ready) you can download <a href="http://corlan.org/downloads/aTabSplitterSkunkwork.fxp">this</a> project file. If you want to run this on a computer without a touch screen you need to make couple of changes (work with MouseEvents instead of TouchEvents, change root node in main.mxml from Application to WindowedApplication).</p>
<p>I can&#8217;t wait to have AIR for Android out and see what people will build!</p>
<div class="shr-publisher-1895"></div><p class='fb-like'><iframe src='http://www.facebook.com/plugins/like.php?href=http://corlan.org/2010/05/19/building-android-apps-with-adobe-air/&amp;layout=button_count&amp;show_faces=true&amp;width=260&amp;action=like&amp;colorscheme=light' scrolling='no' frameborder='0' allowTransparency='true' style='border:none; overflow:hidden; width:260px; height:26px'></iframe></p><img src="http://feeds.feedburner.com/~r/corlan/~4/YzN81esUQuc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://corlan.org/2010/05/19/building-android-apps-with-adobe-air/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://corlan.org/2010/05/19/building-android-apps-with-adobe-air/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=building-android-apps-with-adobe-air</feedburner:origLink></item>
		<item>
		<title>Working with Doctrine 1.x, Zend Framework, and Flex</title>
		<link>http://feedproxy.google.com/~r/corlan/~3/RaJaoeBTgvQ/</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 id="buzz_share_1" style="float: right; margin-right: 10px">
<a rel="nofollow external" target="_blank" href="http://www.google.com/reader/link?url=http://corlan.org/2010/05/05/working-with-doctrine-zend-framework-and-flex/&title=Working with Doctrine 1.x, Zend Framework, and Flex&srcURL=http://worpdressapi.com/">
<img width="52" height="62" alt="" src="http://corlan.org/wp-content/plugins/google-buzz-button//images/buzz.png" original="http://wordpressapi.com/wp-content/plugins/google-buzz/google-buzz.png" border="0" style="display: inline;"/>
</a>
</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" 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
<pre class="brush: cpp;">[/c]
</pre>
<p> = c.name;</p>
<pre style="padding: 0px; font-size: 8pt; 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: