Entries from September 2007 ↓

Magnet opened new office in Ahmedabad

We opened our new office in Ahmedabad last week. The operations started this Monday and the future is bright. Ashok and Vishal are camping there to setup the operations and take Magnet to new heights. We will have a team of about 20 PHP developers there to start with, and expand as we go. We’ve got enough space and infrastructure to scale up quickly and that’s what the plan is!

Thanks to all the people who contributed in setting up the operations in record time!

One more feather to our cap!

PS: Ashok has posted a few photos of the new office here.

 

Cron for Windows

Wanted to deploy an application on a Windows server. The application had features that would work only if cron was setup to call a particular php page at fixed intervals. Doing this on Linux is a job of two minutes. But I did not know how to do cron on Windows. And this is something that I have not even bothered to find out for years!

Always told people that you should be on Linux if you want such features. Windows is not acceptable :)

And if the client persisted, we did a SQL server job setup or Windows Scheduled Task feature!

Today I thought otherwise. Thought I must find some cron replacement for Windows. Couple of searches later, I found pycron. It’s a great free solution for setting up crons just the way you would do on Linux. Comes also with a GUI!

So next time you want to setup a cron on Windows, try out pycron!

 

Taking a snapshot of Flex app, from Flex!

On a recent Flex project, we needed to take a snapshot of what's shown on the screen and save it as an image. I had seen somewhere that this was possible, but couldn't locate how exactly it was to be done. Turns out it's very easy to do such a screen capture / screen grab using Flex.

The essential steps are:

  • Create a new BitmapData object.
  • Copy the target component's pixel data into BitmapData object.
  • Convert the BitmapData object to a PNG encoded ByteArray (using the PNGEnc library)
  • Convert the ByteArray to a Base64Encoded string so that we can send the data safely to the backend.
  • On the backend (PHP via WebORB in our case), decode the data and write it to a file.

Most of the piece come from two places. James Ward has described this technique in his Flex Paint sample. And Tinic Uro has written the PNG Encoder library. Let's see the code now.

Here's the Flex Code:

XML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
  3. <mx:Script>
  4. <![CDATA[
  5. import mx.utils.Base64Encoder;
  6. import mx.rpc.events.ResultEvent;
  7. import mx.utils.ObjectUtil;
  8. import mx.controls.Alert;
  9. import mx.rpc.events.FaultEvent;
  10. import mx.core.UIComponent;
  11.  
  12. public function onResult(event:ResultEvent) :void
  13. {
  14. Alert.show(ObjectUtil.toString(event.result));
  15. }
  16.  
  17. public function onFault(event:FaultEvent) :void
  18. {
  19. Alert.show("Got error: "+event.message);
  20. }
  21.  
  22. public function takeSnapshot(target:UIComponent) :void
  23. {
  24. var bd:BitmapData = new BitmapData(target.width,target.height);
  25. bd.draw(target);
  26. var ba:ByteArray = PNGEnc.encode(bd);
  27. var be:Base64Encoder = new Base64Encoder();
  28. be.encodeBytes(ba);
  29. var encodedData:String = be.flush();
  30. ro.saveImage(encodedData);
  31. }
  32. ]]>
  33. </mx:Script>
  34.  
  35. <mx:Button click="takeSnapshot(targetPanel)" label="Save Image" x="10" y="100"/>
  36.  
  37. <mx:Panel id="targetPanel">
  38. <mx:Canvas backgroundColor="#EEEEEE">
  39. <mx:Label text="Hello World" />
  40. </mx:Canvas>
  41. </mx:Panel>
  42.  
  43. <mx:RemoteObject id="ro" destination="serviceEndpoint" result="onResult(event)" fault="onFault(event)"/>
  44. </mx:Application>

We use WebORB for backend connectivity. Assuming you have the connection in place, we can simply call a method passing the base 64 encoded string and save it on the server. If you don't have RemoteObject / Web Service, you can also use an HTTP POST. The reason to use Base 64 encoding is to get a string we can safely pass around, instead of a byte array.

Here's the PHP side of the code:

PHP:
  1. public function saveImage($encodedPNGData)
  2. {
  3. if ($encodedPNGData != "")
  4. {
  5. $binaryData = base64_decode($encodedPNGData);
  6. $file = "assets/images/something.png";
  7. file_put_contents($file, $binaryData);
  8. return $file;
  9. }
  10. return null;
  11. }

I could resize and do anything else with the image on the PHP side now.

Hope you find some creative use of this :)

 

Crossing the River

Ok, you have seen a few river crossing puzzles, right? Then solve this one!

Instructions:

  • Help these people to cross the river, in the next screen.
  • Only two people at a time, at least one adult.
  • Criminal (in striped dress) cannot be left with others, without the Police.
  • Mother cannot be with sons, while father is not around.
  • Father cannot be with daughters, while mother is not around.
  • Click on the BIG BLUE BUTTON to start!
  • Click on people to get them on or off the boat.
  • Click on the Red buttons to move the boat to opposite side.

For more, checkout FunGloo.

 

Flash, Flex & Web service problems

I always have a tough time deploying a Flash/Flex based app that uses web services. And we use web services (or similar) on almost all projects! Every two or three months I come across a new problem with web service deployment and have to spend some long hours finding and fixing it. The post describes my latest encounter with webservice errors and the fundamental lessons I've learnt about debugging PHP web services used in Flash/Flex/OpenLaszlo.

So, my latest web service error message was:
Request implements version: http://schemas.xmlsoap.org/soap/envelope/ Response implements

Well, that's the only part I could read in the Alert message I had setup for faults in the web service. This was followed by the famous "could not connect to endpoint" error.

I was surprised looking at the error. First thing I did was check the WSDL file. (Yes, am using SOAP webservices). Tried different ways to generate the WSDL from Zend Studio (I use PHP5 web services and Zend Studio for development). Nothing worked. BTW, the problem came only on the live server. The development and staging servers were working perfectly fine with the same files!

After solving the problem, I re-learnt the biggest lesson in web service debugging.

Root cause of almost all web service related problems is some error / warning in your PHP (or other) code.

In this case, the server was not able to include classes and other files that the webservice was using. My PHP based test cases helped solve the problem since they showed up the include errors PHP was having. So let me give you the lesson # 2.

Make sure you write PHP test cases for your web services.

These test cases will use the SoapClient class to call a method on your webservice. Display all errors in the test cases and you will be able to nail the source pretty quickly.

This one is yet unsolved for me! I want to find out a good web service debugger. Something that allows me to pass arguments to the web service and see the entire request and response - including HTTP headers. The WebOrb admin panel does a great job at that, but I would like something that can easily handle complex data! Anything you know of?

Here are some earlier problems I have had with Webservices: