OktoLab GmbH is a small company located in Vienna, Austria, that has specialized in providing hard- and software services in the electronic media sector - mainly video and TV production. This includes renting out equipment like cameras or video editing workstations as well as editing/cutting services and software development. The main customer is Okto TV, a community TV station that runs on public funds.
When I (David Hermann) joined OktoLab in mid-2008, we had to face some serious challenges. The previous (and at that time only) developer had abandoned the company at short notice and left a mess of various software services that were either loosely or not at all coupled:
- a program planning software (PHP4/Postgres)
- a spreadsheet file and a whiteboard with sticky tags to complete the planning stage
- some planning had additionally to be visualized in iCal
- an address book and training session planner (Ruby on Rails/Postgres)
- a user account manager (PHP4/LDAP)
- a TV series manager (Cocoa/Postgres via PHP service)
- an inventory and rental manager (PHP4/MySQL)
- lots of shell scripts for various tasks (bash, PHP)
- a beta Wordpress MU instance for the multi-blog web page
This situation was not caused by the developer, it was a result of the evolution of the company. The situation had gotten out of hand though, so there was a huge pressure to improve it. So here I was in the summer of 2008, a bunch of crude applications without similarities in front of me and a clear instruction what to do next:
"Replace the program planning and TV series software and make them more usable. Make sure to select a solid base to build upon later."
So I did. But how?
The project starts
At that point I had roughly 7 years of PHP experience, both in PHP3/4 (I had been active in the early phpBB community) and OOP PHP5, having completed a huge project a few months before. But this task needed another approach and I started looking for a framework to help me getting the job done efficiently. After some searching and evaluating I had to decide between CakePHP, Zend Framework and symfony. Symfony had just released version 1.1 and I was fascinated immediately by the simple yet extensible way to make things work and the great documentation. After checking all the requirements I decided in favor symfony and I never regretted the decision or had any doubts that this had been the right decision.
Things progressed quickly afterwards. We did a lot of planning and evaluation beforehand, so the everyday workflows could be described as detailed as possible. This was a very important stage of the project, because we found out that the software that had hitherto been used did not fulfill the requirements at all. Aside from that, the planning capabilities for the TV schedule were very limited and unsatisfying.
I quickly created the first few model definitions and user interfaces, and most things worked as expected. Since at that time Doctrine was still not fully stable I had decided to use the more mature Propel as my ORM. This decision also proved fine - I never ran into any serious ORM issues and so I was able to concentrate on the application itself.
Upgrading to symfony 1.2 and getting to know the forms
Shortly after symfony 1.2 was released, I decided to upgrade the project. Since there were quite a few parts that weren't well made (for instance too much code in the controller, and forms with lots of dependencies) I used the opportunity to refactor the most obvious mistakes. Getting the forms right was actually a lot more difficult than expected. The application uses lots of hand-made forms, requiring custom inputs, such as a weekday selector that is saved in a single byte (7 bits) using a bitmap or multiple embedded forms with dynamic adding options.
After a lot of diving into the forms codebase and the at that time not so complete forms documentation I finally got them right and found out how to use the forms correctly. This was one of the hardest parts in 18 months of learning and using symfony, but it was worth every single minute spent: now all the forms do exactly what I want them to do, no matter how complex they are. I've had to write several custom widgets and validators, but once you get used to it it's quite simple and extremely powerful.
JavaScript & AJAX
Another big part of the project was less symfony-related but had to integrate just as well: a fully dynamic calendar view to replace the iCal "solution". I used jQuery for this, and it works well. Connecting the calendar to the symfony application using AJAX was quite easy.
Side note: did you know that there is not a single calendar application or library out there that correctly displays DST switching hours (+1 in March and -1 in October)? I was surprised, but nobody besides TV stations seems to need this functionality! Perhaps there are some working time applications for accounting purposes considering this, but I never saw one.
A few other AJAX functions were just as easy to implement. The clear separation of the controller/action part makes adding AJAX to symfony a piece of cake.
Data and acceptance
From the very beginning of the project it was very important to provide realistic testing data. This was done by creating a command-line importer that pulled all the existing data from the Postgres database and pushed it into the new model. That way the small group of key persons that were our test users always had up-to-date data that could be compared to the existing software.
Another important aspect of enforcing user acceptance was to create an appealing visual style at the very beginning of the project. An external designer did a great job providing a basic template that could be integrated quickly and made the application not only behave great but also look great. Thus the users really looked forward to the official launch day in October 2009, when the old planning software was disabled in favour of the new symfony-powered program planning tool.
Connecting the rest of the world: the API
Using the powerful REST capabilities of symfony it was easy to implement both reading and writing interfaces that support various output formats for various connections to the outside world. These interfaces include the generation of video text, the online program on the web site, the playlists for the playout server and many more. Once again symfony shows its powerful flexibility and easy to use syntax.
One of the most important interfaces is the one for program data exchange. There are lots of "consuming" applications that need to know about the TV schedule. Most of them receive the data in a simple XML format.
- Whenever a new file is played on the playout system, a script asks for the oncoming program data to update the on air video text.
- The homepage schedule overview is updated 5 times a day by fetching the data for the next 3 weeks and uploading it to the web server.
- Using a simple XSL transformation the same XML data can be converted to iCal format to make it viewable in any calendar application.
- Providing the program by series (e.g. for series-specific pages) in RSS format will be available soon.
- For exchanging the schedule with TV magazines it is also provided in various proprietary XML formats. The content is pulled from the API and uploaded to the magazine's FTP servers.
The API is also used to exchange content meta data with cooperating community TV stations and public media archives. Contrary to the program API this one also provides write access.
Furthermore some series related meta data is published both to the video text server and the website on a regular basis.
The API is available through a symfony application that is separated from the frontend, so it can use different security and caching options. This would also easily allow the API to run on a different server for external access.
Another migration: symfony 1.3/1.4
Currently (early 2010) the program planning software is being ported to symfony 1.4. Most of the work is already done (it was not that much since the code was quite clean to begin with) and there were no unexpected difficulties, so it's only minor things that have to be adapted, e.g. some form widgets which extend other widgets that have changed slightly. Considering that symfony 1.4 will have 3 full years of support the complete lifecycle of the software will at least span 4 years in a stable environment, which is quite a long time in this fast-pacing world of web software.
What about all the other projects?
After the initial phase was completed and the program planning software started taking shape, the other applications were also partly rewritten or modernized. By mid-2010 every single application at Okto TV will run on symfony - even the Wordpress website will have been replaced by a symfony-powered CMS (this is a work in progress). All the various interfaces between the applications will be using clean REST implementations. This is 2 years total for replacing every single application and that's actually quite short.
All this would never have been possible without the powerful features and flexibility of symfony. The program planning software alone now uses more than 60 database tables, with more being added on a regular basis, and since the most important components have been decoupled using the event dispatcher instead of direct calls there is a lot of room for further expansion.
Another interesting project that was not in the original 2008 plan is the automation of various video handling tasks like format conversion. The batch queue system that was created for this purpose is close to being finished, but it includes enough interesting details for another full article.
Organizational impact
After that much work going into the creation of lots of new software the most important question from the customer's point of view is: what's the gain? Altogether we can see a reduction in time needed to get things done of about 30%. Yes, the new software saves roughly a third of the time the old software required to do even less! And that's not 30% of 1 person - it's 30% of 4 persons, making one of them fully available for other tasks like quality or content checks on video material. Checking videos is even more interesting than pushing around broadcast dates in iCal!
This was mainly achieved because so much time went into analyzing and optimizing all the workflows. Planning a day alone took 3-4 hours in the past and is finished in roughly 10 minutes today (and much less error prone). Without symfony's flexibility this would not have been possible!
About the author
David Herrmann is a mechanical, electronics and software engineer close to his 30ies who loves any kind of technical stuff as long as it provides new creative ways of being used. He has been coding in lots of languages on all kinds of platforms, but mostly in PHP, Java and JavaScript. When not working, David is spending time with his family or on his bicycle. He sometimes writes about software development on blog.vworld.at
This case study was provided by a user of the symfony framework and published with the permission of all parties involved. Are you interested in having your case study published on the symfony blog? Feel free to contact our Community Manager Stefan Koopmanschap (stefan.koopmanschap - at - symfony-project - dot - com).
This kind of case studies are quite interesting, not only showing that symfony is really useful but also providing new perspectives on software management. Thank you! :D
After the migration from 1.1 to 1.2 (and now to 1.4), did you stick with Propel or migrate to Doctrine too?
Weirdest thing is I've been doing almost exactly the same thing for the local television broadcaster in Amsterdam. (Same history as well with all kind of different apps an Wordpress MU) Unfortunately, the project has become so huge that a migration from 1.1 to 1.4 is a major undertaking. (The cms is driving a lot of external stuff like teletext and some social media publications)
Thanks for the positive feedback :-)
@Davide: we stayed with Propel because switching to Doctrine would have caused nothing but headaches. There's just no reason to switch because Propel works great and scales great so far. I also personally prefer getters and setters to directly accessing properties, out of 3 reasons: a) it feels cleaner (that's the Java guy in me speaking ;-) and it allows for cleaner interfaces b) I had to override lots of getters and setters for various reasons c) setter chaining is one of the greatest inventions in the history of mankind ;-)
I agree with all your reasons. That's why I still use Propel :)
Nice article, David. Just a remark on your last comment... Doctrine does support getters and setters. Perhaps not when you were first looking at it, but I use them all the time, as I also prefer them to directly accessing properties.
@Steven: I know that Doctrine supports getters and setters, we are also using Doctrine in one side project (the inventory software replacement). Nearly all the documentation seems to advocate accessing the class members directly though, so it's not official best practice (which I think of as a bad thing).
@Marc: out of curiosity: which local broadcaster is that? You may also email me: david [[at]] vworld.at ;-)
Hey David - great article!
I was wondering, since the event dispatcher is a fairly new and powerful concept, and you said you're using it extensively, maybe you could show some examples of how you use it? That would rock.
Thanks, Daniel
@Daniel: you're right, that's something I could write about. It will take some time though...
A complete book on this case study would be so helpful ;)