Archive for December 2011

Painless (well, less painful) migration to Symfony2

Over the past months I’ve talked to several companies that run a symfony 1 codebase, sometimes as old as symfony 1.0, which is big, very big. Often these applications or websites are at the heart of their business. Yet, Symfony2 is stable now, and symfony 1 support is going to stop at some point. Regularly, they ask me for advice on migrating their legacy codebase to a brand new Symfony2 project. Often enough, I have to inform them that migration from a symfony 1 to a Symfony2 codebase is a lot of effort and a huge investment in time (and therefore money). Many companies then wonder whether they should do it at all. The thing is, there is no need to do it all at once.

Gradual migration

It is much easier to do a gradual migration. Start with one part of your application, and bit by bit migrate your logic and application. The traditional way of doing such migrations is to create a new project and have parallel development on the old and the new version of the application. The problem with this, though, is that when you make a change to your old application, you have to make the same change in the new codebase, essentially doubling the amount of work for each feature you need to implement.

Wouldn’t it be much cooler if you only need to change this once? This is of course an option. You could wrap your old application into your Symfony2 application, and have different parts of your application be handled by different versions of your codebase. Once you’ve ported a new section of your application to Symfony2, you change the routing in your application to point those URLs to your Symfony2 bundle instead of your old symfony 1 project, and that part is done. You can move on to the next part.

A word of caution

While this approach is ideal because you can migrate in several phases, there are some issues with this approach. First of all, this will have a performance impact on your application. Instead of a single framework, you now use two frameworks for all your legacy pages. Result: An extra overhead because, well, two frameworks add more overhead than one. And though Symfony2 is in this case only a proxy, it does add an extra layer. Of course, you can use the cool caching features of Symfony2 to add a caching layer in front of your symfony 1 application (which might actually speed up your application), but this definitely does not apply to all projects. So before simply applying some caching to your application, think about whether it will work. And keep testing :)

Another issue is sessions. If your application works with authentication and authorization, you’ll now have to work with two different systems that have a different approach to authentication and authorization. So far, I have not yet figured out how to manage this, but in the projects I’ve used this approach for so far, I didn’t really need to do this. But this is something you really need to consider.

A tool

I created a simple bundle that could assist in using this approach. The IngewikkeldWrapperBundle adds a simple fallback route in your Symfony2 application, so that any URL not handled by your Symfony2 application is automatically forwarded to your legacy codebase. The legacy codebase handles the request and returns the response, and that’s it. And once you’ve had the time to work on porting a new part of the codebase to Symfony2, you simply add a route to your new bundle that matches the old URL pattern for that part of your application, and Symfony2 starts serving that part instead of symfony 1.

Drawing with CSS3

The latest CSS specification (also known as CSS3) has introduced a set of new properties which allow the developer to implement a lot of interesting effects on a web page. It is now possible to have round corners, shadows or even create nice background patterns. Inspired by others who had done amazing things with CSS3 we wanted to give it a try ourselves in order to get some first hand exposure to the new properties and see how much effort was required to do a little experiment with CSS3. We decided to try to draw our company’s logo using only CSS3.

This is the original logo:

How can you create such an image?

When drawing something with CSS, you first need to slice your image in smaller pieces (usually rectangles) and then separately implement every part of the image with CSS. Then you just need to position the pieces correctly so that it forms an image.

For example, shapes can be rendered styling only a <div> element:

-> a circle

#circle {
  background-color: red;
  border-radius: 50%;
  width: 100px;
  height: 100px;  /* if set to 200px it becomes an elipse for example */
}

-> one or multiple triangles

#triangle {
  /* border-color: transparent transparent red transparent; /* red triangle*/
  border-color: green blue red orange; /* multiple triangles*/
  border-style: solid;
  border-width: 100px;
  width: 0px;
  height: 0px;
} 

-> outlines:

 #outlines {
  background-color: orange;
  box-shadow: 0 0 0 10px red, 0 0 0 20px blue, 0 0 0 30px green, 0 0 0 40px silver;
  width: 20px;
  height: 20px;
} 

-> multi-columns:

#columns {
  /* vendor prefixes for gradients are required as currently no browser implements it without prefixes */
  background: linear-gradient(0, orange 50%, green 50%);
  background-size: 50px;
  width: 200px;
  height: 100px;
}

-> background patterns:

#patterns {
  /* note vendor prefixes for gradients are required */
  background: linear-gradient(45deg, silver 25%, orange 25%, orange 50%, silver 50%, silver 75%, orange 75%, orange);
  background-size: 50px;
  width: 200px;
  height: 200px;
} 

The image below displays the resulting drawings created with the above codes.

If you have a modern browser, thanks to Lea Verou‘s interactive CSS playground dabblet you can check on this page how it would be rendered in your browser (some additional shapes are included too) as well as edit the CSS.

Now that we have seen the kind of things that can be achieved with the new properties on a single <div> element, let’s go back to our logo. We initially thought that we could try to create a flexible CSS3 image that would render properly when the logo would be scaled to different sizes. We tried to use percentages to set all the sizes instead of pixels. Unfortunately, this did not work well as it turned out that browsers handle percentages differently. On this page you can find an image that shows how different browsers rendered differently the logo when implemented using percentages.

This is just an example of what can go wrong with different implementations of the standard and why it is important to test with different browsers to ensure that the user gets the same experience independently of the browser they are using.

If we stick to fixed sizes (in pixels) the result provides a consistent experience in all the browsers we tests. You can take a look at the result: the CSS3 LeaseWeb logo!

It took me a couple of hours to come up with the first structure and a couple more for the tweaking. With some CSS knowledge, a bit of patience and creativity you can draw amazing images with CSS3.

Developing a mobile web application with IUI

At LeaseWeb we have a hosting control panel called “Self Service Center” or SSC. We are starting to make our first steps into making the Self Service Center available on a mobile platform.

We have a couple of options on how to implement this:
• Build native applications for each mobile platform ( mainly Android & iOS )
• Build a mobile accessible website

We had to make a list of advantages and disadvantages of the 2 options:

We prefer to keep a single code stack, for maintenance reasons, and so we can make every feature immediately available in the mobile version. This is why we decided to make a proof-of-concept of a mobile accessible website.

The first problem we encountered was to find out how to implement this mobile website the best way possible in the Symfony framework. At first, we checked if this was possible by doing only CSS changes, so without touching the templates. It did not took us long to come to the conclusion that this was not enough and we had to revise all of the templates.

By looking up the API of the Symfony framework on a mobile device we saw that they had a mobile version of it on their website. We were very curious what technology they used and how they implemented it, so we started digging. We found out that they were using the IUI framework on their mobile API page and although it didn’t work flawlessly we were impressed with the way it worked.

So what is this IUI and how does it work?
With IUI you have to think of your webpage as 1 big HTML file which you keep adding content to. So you keep updating your current HTML with new adaptations through AJAX request. When you click a button / link the new page is loaded off-screen. When the screen is loaded it slides smoothly into your screen. The old screens are not unloaded so you can smoothly slide back to the previous screen using the back button in the upper left corner.

Figure 1 – The red box shows the area that is visible on the screen, the other pages can slide in.

Using this framework you can make any webpage feel like a native iPhone application. A single IUI web page can contain multiple related iPhone screens. This makes IUI map on the Symfony MVC framework quite nicely, because all the data of a single MVC view will not fit on one iPhone screen, but it might fit on multiple.

Also for backend developers it is really nice that you don’t have to design all the screen layouts. You can just follow the layout that is provided with the framework and your screens immediately look professional. Although we created an impressive proof-of-concept there were some problems we did encounter:

A broken back button
When you post a form with validation errors, the same page – containing the form – is loaded with the errors displayed next to the input fields. This new page has the same id as the old form causing the back functionality to be broken.

The IUI back functionality works using a “stack”. This stack contains the ids of the previously loaded pages and forms. When the page loads it adds the id to the stack. When a validation error has occurred the stack contains the wrong values, because the validated form and the original form have the same id.

The possible solutions we found are:
1) To fix this we can give the validated form a different id than the original form.
2) Show the (validation) errors on a new page or popup.

An iPhone like way to handle field validation error is to show popups containing the validation errors. This can be achieved in IUI using “Dialog” type forms. First we tried using JavaScript “alert” calls but we had trouble, because these pop-ups are blocking and it is hard to use them without modifying IUI internals.

Displaying flash messages
More or less the same problem occurs when displaying “flash” messages. “Flash” messages are messages often colored yellow, red or green (for warnings, errors and confirmations) and are set on top of the screen displaying the results of the last page load. In IUI the flash messages are not working properly because pages are not reloaded on “back button” navigation. In an iPhone application these messages typically show in a popup.

Conclusion
We think IUI is a good and easy way to convert your current website to a mobile website in a MVC framework. Problems we encountered are related to error and status messages that a typical web application shows inside (and on top of) forms. Unfortunately IUI does not seem prepared for showing these. We’ve found a workaround by showing these messages in “Dialog” type forms.

LeaseWeb Self Service Center – https://secure.leaseweb.com
IUI framework – http://www.iui-js.org/
Symfony framework - http://www.symfony-project.org

Subversion revision information in the Symfony debug toolbar

At LeaseWeb we are very serious about software development and that is why we hire software testers. These people do risk analysis, think of new test cases, execute them and organize them in test suites using TestLink. We also use PHP and are great fans of the Symfony MVC framework. Being serious about Agile software development means that we do TDD using unit tests and functional test. For this we use the Symfony build-in unit and functional tests. We also use Selenium for creating browser-driven test suites. The advantages of Selenium over the functional tests in Symfony are cross browser testing and JavaScript testing.

We have this product called “SSC” (this is the hosting control panel for the customers) and we test it thoroughly and often. For this product we have a DTAP environment to do testing and acceptance testing. Within the tests of this product the testers encountered a challenge: How do the testers know what revision of our application they are testing and what branch they are testing? This is especially a problem with acceptance testing where interactions between various systems are tested. Because the testers do not have command line access on the Linux machines that run the acceptance environment they cannot simply issue the “svn info” command like developers can.

To solve this problem we wrote a Symfony plugin called “lwTestingInformationPlugin”. It shows the “svn info” command output in a popup that is accessible from the Symfony debug toolbar. Even though it was extremely easy to write, it could be very useful. We made it available for download, so if you think it might be useful for your project as well, please try it and send us your feedback!

Click here to download the plugin (lwTestingInformationPlugin.tar)

TestLink = http://www.teamst.org/
Symfony = http://www.symfony-project.org
Selenium = http://seleniumhq.org/
Subversion = http://subversion.apache.org