Switched to Ubuntu and all is well
Update: After three days of using the Flex Builder plugin i just relized that it does not support design view yet! Well that would be nice!
Running Ubuntu as my primary OS and AIR, Flex Builder Plugin, PDT, Charles, Vmware Workstation FileZilla, all work great. It took me longer to backup everything from my Vista install than it did to get everything back up and going. Vista was my first Windows OS since Windows ME when I switched to Linux. Post college (aka cash) I became a mac guy but purchased a Dell M90 about a year or more ago when the whole switching to the intel architecture thing was going on. I had two power macs in a row that the monitor stoped working and out of frustration moved to what seemed like a super powerful laptop. Although I liked OSX 10.0 - 10.3 the powerpc hardware left me with a lot to be desired and I still hope that other hardware vendors can someday install OSX. I decided this weekend that there was no way I was getting a new mac any time soon (1 kid another on it's way no $) and with the change to Linux I may never go back. Unfortunately I still need Flash CS3 which requires windows so VMware it is until Flash looks a lot more like eclipse.
2 commentsMN.SWF/Camp/ presentation files
Here are the files for the presentation that I am giving today at MN.swf Camp. Now that it is one in the morning and Minneapolis is 3.5 hours away I better head off to bed. I hope they have quality coffee!
Presentation in PDF, Database Creation, Examples
amfphp-swfcamp.zip
Flash Player 9.0.124 beta allows testing against security model changes
Trying to find a way to test your sites compatible with the new Flash Player security model! The newest/test Flash Player is in Flex 3 Beta download called ‘Adobe Add-ons' for Open Source Flex SDK bundle that is about 58MB. You can download here: http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+3
Download the latest nightly build as the milestone release has the released Flash Player 9.0.115.
Adobe Add-ons for Open Source Flex SDK – This package contains all of the items that are in the Adobe Flex SDK and not in the Open Source Flex SDK. Downloading this file will allow you to bring the Open Source Flex SDK to parity with the Adobe Flex SDK. This package includes the Adobe Flash Player, Adobe AIR, the advanced font encoding libraries, and the code that allows licensing of things like the Data Visualization components. All of these elements are licensed under the Adobe Flex SDK license.
I downloaded the nightly build from and traversed the extracted zip for my windows computer to
flex_sdk_3.0.1.1092_add-on\runtimes\player\win\Install Flash Player 9 Plugin.exe
ran the installer and was up and running with Flash player 9.0.124 installed in Mozilla.
Preparing for the Flash Player 9 April 2008 Security Update
Read this post for how to make changes for amfphp:
Updated: crossdomain.xml fixes amfphp for april flash player release
Thanks Peter Kehl for getting me an updated link!
Check Out Flash Switcher a firefox plugin that allows you to run lots of flash player versions. This way you can use this for testing but keep your debug player installed as the default for Flex Builder!
3 commentsAMFPHP Browser syntax for testing services.
The Service Browser uses the remoting gateway to present a list of service classes and their methods. By selecting one of your methods, you will be presented with a page that allows you to call it; by entering arguments and observing the output in the “results” tab below, you can test remoting methods here.
The text inputs for arguments accept arguments in JSON (JavaScript Object Notation) or “object literal” format; essentially, valid ECMAScript (JavaScript/ActionScript) syntax.
String arguments can be entered directly without requiring quote marks, and number arguments can be entered directly as well.
To pass an array as an argument, use the JSON/ECMAScript array literal syntax – comma-separated values between square brackets. For example, if the parameter expects an array of numbers, you would enter it something like:
[1, 3, 5.5, 44]
A two-dimensional array in JSON format is entered as an array of arrays like this:
[[1, 2, 3], [5, 7, 15], [1, 7, 2]] .
Objects (such as VOs) can also be input here, using JSON/ ECMAScript object literal syntax like this:
{id: 1, label: ‘A label’, notes: ‘Some notes’}.
Objects and arrays can also be nested inside each other:
[{id: 1, label: ‘first object’}, {id: 99, label: ‘object with an array in it’, numbers: [13, 44, 97]}, {id: 34, label: ‘object with another object in it’, thing: {‘things’: 14, ‘gadgets’: 6, ‘tchockies’: 0}}]
In addition to numbers and strings, these are all valid types of arguments an AMFPHP remoting method can accept.
For more about JavaScript/ActionScript array-literal syntax and the object/associative-array duality of ECMAScript, consult your friendly neighborhood Internet.
Note that for some reason the service browser does not much care for double-quotes, so when entering object arguments, use the single-quote format for strings.
Also note that currently, although PHP supports optional arguments to a method by specifying a default value in the method signature, the service browser does not have a way to “skip” entering an argument. If you leave an input box blank, the parameter will receive an empty string.
3 commentsapache mod_security oddity in AMFPHP
An AMFPHP user gave me a run for my money on debugging an error on a new server. Come to find out mod_security can play a little havoc on AMFPHP and even though the gateway.php file executes correctly. When you open up the amfphp/browser you will get the following error which will also be your fault event in your application.
(mx.rpc::Fault)#0 errorID = 0faultCode = "Client.Error.MessageSend"faultDetail = "Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Failed"faultString = "Send failed"message = "faultCode:Client.Error.MessageSend faultString:'Send failed' faultDetail:'Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Failed'"name = "Error"rootCause = (Object)#1code = "NetConnection.Call.Failed" description = "HTTP: Failed" details = "http://somedomain.com/amfphp/gateway.php" level = "error"
when you call a service it gives the following error.
403 Forbidden Forbidden You don't have permission to access /amfphp/gateway.php on this server. Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request. Apache/1.3.39 Server at domainname.com Port 80
So if you are seeing this error when you try and connect to your gateway in charles / service capture look at a phpinfo page and see if mod_security is installed. If it is then in order to fix this error you need to create an .htaccess file in the amfphp/gateway.php directory and place the following content in it.
<ifmodule>SecFilterInheritance Off </ifmodule>
Hope that helps. If anyone knows more about this module please let me know what really is going on as I would love to understand why a security module is stopping amfphp.
1 commentUpdated: crossdomain.xml fixes amfphp for april flash player release
This updated crossdomain.xml example fixes all of the issues that people were having with the last post that I had. Please update your server with the following file. Remember that you need to remove any spaces as this has to be well formated xml! Make sure that you place the file in your web root directory of the top level domain of the site. This is commonly the public_html or www directory in the server so that you can access the file at www.yourdomain.com/crossdomain.xml
If you do not add this file you will get a Error #2044: Unhandled SecurityErrorEvent:. text=Error #2048: Security sandbox violation:
Which will toss an error that looks something like this out of the player.
<cross-domain-policy> <!-- Place top level domain name --> <allow-access-from domain="yourdomain.com" secure="false"/> <allow-access-from domain="yourdomain.com" to-ports="80,443"/> <allow-http-request-headers-from domain="yourdomain.com" headers="*" /> <!-- use if you need access from subdomains. testing/www/staging.domain.com --> <allow-access-from domain="*.yourdomain.com" secure="false" /> <allow-access-from domain="*.yourdomain.com" to-ports="80,443" /> <allow-http-request-headers-from domain="*.yourdomain.com" headers="*" /> </cross-domain-policy>
Again the purpose of a crossdomain.xml file is to allow external domains to access your content. What has changed in the new release is that we can not change the header anymore even if its on the same domain name. This means that you need to add a crossdomain file even if you are not accessing your amfphp installation from an external domain name. More information on policy files!
Preparing for the Flash Player 9 April 2008 Security Update
7 commentsSpeaking at SWFCAMP: N-Tier Development with AMFPHP
I am going to being making a presentation on AMFPHP at SWFCAMP which is put together by the Adobe users group mn.swf. If you are going to be attending the confrence make sure you say hi! Also post a comment if there is something specific that you would like to hear about.
N-Tier Development with AMFPHP
In this session you will learn the basics of setting up an AMFPHP PHP environment. We will then walk through a CRUD (create, read, update, delete) example in both Flash CS3 and Flex. You should leave this session with confidence in starting to use AMFPHP in building your business logic and data tiers for future Flash Player based applications. Throughout the session we will describe some of the tips and tricks for optimizing AMFPHP with information on class mapping, Authentication, ArrayCollection’s, and AMFEXT, which will keep the attention of even the most veteran RIA developer.
AMFPHP ArrayCollection
AMFPHP does not natively convert Arrays to ArrayCollections, and there is no ArrayCollection class to speak of for PHP. You may sometimes need ArrayCollection typed values to be returned within a VO. There are three fixes that I've found for this.
Fix 1
If you are just expecting an ArrayCollection as the result of a PHP service call then simply create an ArrayCollection out of the returned Array from PHP. The following AS3 casts the returned array into an array collection.
private function result(data:Object):void{ var someDataProvider:ArrayCollection = new ArrayCollection(data.result); }
Fix 2
If you need ArrayCollection values within a VO, rather than doing a simple cast (well, really its an instantiation), you should create the ArrayCollection type in PHP.
class ArrayCollection{ public $_explicitType = "flex.messaging.io.ArrayCollection"; public $source = array(); function ArrayCollection(){ $this->source = array(); } } ?>
Then, whenever a value is expected to map to ArrayCollection within Flex, use ArrayCollection in PHP!
class SomeVO{ public $someArray = ArrayCollection(); ... $someArray->source[0] = "something"; } ?>
Fix 3
This fix is very quick and easy, but don't expect it to work ALL the time. The idea is to throw your Array into a RecordSet constructor and return that instantiation in the service call. If your call is AMF3 it will return an ArrayCollection and AMF0 will return a RecordSet.
return new RecordSet($myArray);
This works great for returning associatively indexed values ([or] results from a database query), but straight up [0,1,2] Arrays will not work.
Thanks Chad Callahan for putting this cheat sheet together!
5 commentsApril Flash Player Update breaks AMFPHP
Updated: crossdomain.xml fixes amfphp for april flash player release
In April Adobe will release a new version of the Flash Player that now requires policy files for certain actions. If you are using AMFPHP you will need to add a crossdomain.xml file to your website to allow the sending and receiving of custom headers from flash to your server. Please make sure that you have a policy file in the document root of the web server that hosts your amfphp services on.
Here is an example crossdomain.xml policy file that will do the trick! Update the domain name to the name of the webserver that hosts your swf file.
<cross-domain-policy>
<site-control permitted-cross-domain-policies="all">
<allow-access-from domain="*.yourdomain.com">
</allow-access-from>
<allow-http-request-headers-from domain="*.yourdomain.com" headers="*">
</allow-http-request-headers-from>
</site-control>
</cross-domain-policy>
Eventually I will walk through all the headers that AMFPHP needs an update this policy file and add it to the template. If you want the new player now it is included in the Flex 3 Beta SDK download. 22mb. You can get it installed and test that your application works! Update:Flash Player 9.0.124 beta allows testing against security model changes
Flash CS3 DataGrid with AMFPHP & MySQL
Everyone seems to want to know what the simplest way is to populate a Flash CS3 DataGrid from AMFPHP and MySQL. This is trivial in Flex however I found that it was difficult in Flash Cs3 without a good understanding of AMFPHP. So here is the super simple example, plus a utility to help out.
First AMFPHP returns all AMF3 result resources as an ArrayCollection. This is great if you are working in Flex Builder. If you are working in Flash Cs3 AND you have not mapped your Flex library's into Flash this is a problem.
Lets start by creating a MySQL database named products. Run the following SQL against the database to get a table Product and some data in the table. This is worth getting this database going as I am working on all the examples of remoting that mimic the BlazeDS quickstart guide!
CREATE TABLE `Product` ( `PRODUCT_ID` int(11) NOT NULL auto_increment, `NAME` varchar(40) NOT NULL default '', `CATEGORY` varchar(40) NOT NULL default '', `IMAGE` varchar(40) NOT NULL default '', `PRICE` double NOT NULL default '0', `DESCRIPTION` varchar(255) NOT NULL default '', `QTY_IN_STOCK` int(11) NOT NULL default '0', PRIMARY KEY (`PRODUCT_ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=19 ; -- -- Dumping data for table `Product` -- INSERT INTO `Product` VALUES(1, 'Nokia 6010', '6000', 'Nokia_6010.gif', 99, 'Easy to use without sacrificing style, the Nokia 6010 phone offers functional voice communication supported by text messaging, multimedia messaging, mobile internet, games and more.', 0); INSERT INTO `Product` VALUES(2, 'Nokia 3100 Blue', '9000', 'Nokia_3100_blue.gif', 109, 'Light up the night with a glow-in-the-dark cover - when it is charged with light you can easily find your phone in the dark. When you get a call, the Nokia 3100 phone flashes in tune with your ringing tone. And when you snap on a Nokia Xpress-on gaming co', 99); INSERT INTO `Product` VALUES(3, 'Nokia 3100 Pink', '3000', 'Nokia_3100_pink.gif', 139, 'Light up the night with a glow-in-the-dark cover - when it is charged with light you can easily find your phone in the dark. When you get a call, the Nokia 3100 phone flashes in tune with your ringing tone. And when you snap on a Nokia Xpress-on gaming co', 30); INSERT INTO `Product` VALUES(4, 'Nokia 3650', '3000', 'Nokia_3650.gif', 200, 'Messaging is more personal, versatile and fun with the Nokia 3650 camera phone. Capture experiences as soon as you see them and send the photos you take to you friends and family.', 11); INSERT INTO `Product` VALUES(5, 'Nokia 6820', '6000', 'Nokia_6820.gif', 299.99, 'Messaging just got a whole lot smarter. The Nokia 6820 messaging device puts the tools you need for rich communication - full messaging keyboard, digital camera, mobile email, MMS, SMS, and Instant Messaging - right at your fingertips, in a small, sleek d', 8); INSERT INTO `Product` VALUES(6, 'Nokia 6670', '6000', 'Nokia_6670.gif', 319.99, 'Classic business tools meet your creative streak in the Nokia 6670 imaging smartphone. It has a Netfront Web browser with PDF support, document viewer applications for email attachments, a direct printing application, and a megapixel still camera that als', 2); INSERT INTO `Product` VALUES(7, 'Nokia 6620', '6000', 'Nokia_6620.gif', 329.99, 'Shoot a basket. Shoot a movie. Video phones from Nokia... the perfect way to save and share life’s playful moments. Feel connected.', 10); INSERT INTO `Product` VALUES(8, 'Nokia 3230 Silver', '3000', 'Nokia_3230_black.gif', 500, 'Get creative with the Nokia 3230 smartphone. Create your own ringing tones, print your mobile images, play multiplayer games over a wireless Bluetooth connection, and browse HTML and xHTML Web pages.', 10); INSERT INTO `Product` VALUES(9, 'Nokia 3120', '3000', 'Nokia_3120.gif', 159.99, 'Designed for both business and pleasure, the elegant Nokia 3120 phone offers a pleasing mix of features. Enclosed within its chic, compact body, you will discover the benefits of tri-band compatibility, a color screen, MMS, XHTML browsing, cheerful screen', 10); INSERT INTO `Product` VALUES(10, 'Nokia 3220', '3000', 'Nokia_3220.gif', 199, 'The Nokia 3220 phone is a fresh new cut on some familiar ideas - animate your MMS messages with cute characters, see the music with lights that flash in time with your ringing tone, download wallpapers and screensavers with matching color schemes for the', 20); INSERT INTO `Product` VALUES(11, 'Nokia 6680', '6000', 'Nokia_6680.gif', 222, 'The Nokia 6680 is an imaging smartphone that', 36); INSERT INTO `Product` VALUES(12, 'Nokia 6630', '6000', 'Nokia_6630.gif', 379, 'The Nokia 6630 imaging smartphone is a 1.3 megapixel digital imaging device (1.3 megapixel camera sensor, effective resolution 1.23 megapixels for image capture, image size 1280 x 960 pixels).', 8); INSERT INTO `Product` VALUES(13, 'Nokia 7610 Black', '7000', 'Nokia_7610_black.gif', 450, 'The Nokia 7610 imaging phone with its sleek, compact design stands out in any crowd. Cut a cleaner profile with a megapixel camera and 4x digital zoom. Quality prints are all the proof you need of your cutting edge savvy.', 20); INSERT INTO `Product` VALUES(14, 'Nokia 7610 White', '7000', 'Nokia_7610_white.gif', 4500, 'The Nokia 7610 imaging phone with its sleek, compact design stands out in any crowd. Cut a cleaner profile with a megapixel camera and 4x digital zoom. Quality prints are all the proof you need of your cutting edge savvy.', 7); INSERT INTO `Product` VALUES(15, 'Nokia 6680', '6000', 'Nokia_6680.gif', 219, 'The Nokia 6680 is an imaging smartphone.', 15); INSERT INTO `Product` VALUES(16, 'Nokia 9300', '9000', 'Nokia_9300_close.gif', 599, 'The Nokia 9300 combines popular voice communication features with important productivity applications in one well-appointed device. Now the tools you need to stay in touch and on top of schedules, email, news, and messages are conveniently at your fingert', 26); INSERT INTO `Product` VALUES(17, 'Nokia 9500', '9000', 'Nokia_9500_close.gif', 799.99, 'Fast data connectivity with Wireless LAN. Browse the Internet in full color, on a wide, easy-to-view screen. Work with office documents not just email with attachments and memos, but presentations and databases too.', 54); INSERT INTO `Product` VALUES(18, 'Nokia N90', '9000', 'Nokia_N90.gif', 499, 'Twist and shoot. It is a pro-photo taker. A personal video-maker. Complete with Carl Zeiss Optics for crisp, bright images you can view, edit, print and share. Meet the Nokia N90.', 12);
Here is a very simple ProductService which has two methods. The constructor that creates the DB connection and GetProducts a select * result that returns all rows. Upload the ProductService.php file into your amfphp/classes directory. Check out the service in the AMFPHP Service Browser for fun and debugging your db connection!
class ProductService { var $dbh; public function __construct() { $this->dbh = mysql_connect ("localhost", "wade", "arnold") or die ('I cannot connect to the database because: ' . mysql_error()); mysql_select_db ("product"); } function getProducts() { return mysql_query(sprintf("SELECT * FROM Product")); } }
From Flash CS3 place a DataGrid on the stage and give it an instance name of products_dg. Place a button on the stage and give it an instance name of getProducts_btn and change the label to Get Products
Create a document Main.as class and link the new fla to the class. Copy the following code into the Main.as file and update the gateway url to your AMFPHP installation.
package { import flash.display.MovieClip; import fl.events.*; import flash.events.*; import flash.net.NetConnection; import flash.net.Responder; import fl.data.DataProvider; import ArrayCollectionDP; public class Main extends MovieClip { private var gateway:String = "http://localhost/amfphp/gateway.php"; private var connection:NetConnection; private var responder:Responder; public function Main() { getProducts_btn.addEventListener(MouseEvent.CLICK, sendData); responder = new Responder(onResult, onFault); connection = new NetConnection; connection.connect(gateway); } public function sendData(e:MouseEvent):void { connection.call("ProductService.getProducts", responder); } private function onResult(result:Object):void { products_dg.dataProvider = ArrayCollectionDP.toDataProvider(result); } private function onFault(fault:Object):void { trace(String(fault.description)); } } }
Create a new ActionScript 3 file called ArrayCollectionDP.as and copy the following code into it. This class is designed to convert an AS3 ArrayCollection into a dataprovider. This is necessary until Adobe adds by default ArrayCollection to Flash Cs3. I have no idea why this class is not part of Flash but I also don't work at Adobe.
package { import fl.data.DataProvider; public class ArrayCollectionDP { public static function toDataProvider(myArrayCollection:Object):DataProvider { var values:Array = myArrayCollection.serverInfo.initialData; var category:Array = myArrayCollection.serverInfo.columnNames; var aArr:Array = new Array(); for (var i:Number=0; i < values.length; i++) { aArr[i] = new Object(); for (var aIndex:* in category) { aArr[i][category[aIndex]] = values[i][aIndex]; } } var dp:DataProvider = new DataProvider(aArr); return dp; } } }
This class allows you to take the ArrayCollection result from AMFPHP and pass it through the class to get a DataProvider. The datagrid's dataprovider can now be set simply.
You end up getting something that looks like this!
You should be able to take this example and start making your application right away. The ArrayCollectionDP.as class can be reused in the future! Let me know if this helps or of course if you get stuck. I will be using this example on amfphp.org soon with more details and of course all the source files!
16 comments



