Posts Tagged ‘D4 Framework’

Captain’s Log(2)

Friday, September 4th, 2009
http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/digg_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/reddit_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/dzone_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/stumbleupon_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/delicious_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/blinklist_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/technorati_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/google_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/myspace_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/facebook_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/yahoobuzz_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/twitter_32.png

Welcome to the 2nd installment of Captain’s Log()!

Today I’d like to talk about refactoring. Wikipedia defines refactoring as “the process of changing a computer program’s internal structure without modifying its external functional behavior or existing functionality, in order to improve internal quality attributes of the software, for example to improve code readability, to simplify code structure, to change code to adhere to a given programming paradigm, to improve maintainability, to improve performance, or to improve extensibility.”

As web developers, we’re forced to keep up with the latest technologies and best practices, which can extremely difficult because the rate at which these things change is incredibly fast. It changes so fast that as soon as we finish developing a website, a lot of the techniques and best practices that we used have become outdated. In order to keep up with the latest trends, we simply apply the new techniques and best practices to the next project, which seems to work well most of the time.

But what happens when you need to update an old website with the latest technologies and best practices? If the website is only a few weeks old, it’s usually just a case of refactoring a few classes, or modifying the way the application is bootstrapped. However, if the website is months - or god forbid, years - old, then it becomes an insanely difficult task.

Recently, I’ve been tasked with updating an old website to use the latest technologies and best practices. And by “old”, I mean 4 years old. That’s right, 4 years. As you can imagine, that’s a lot of refactoring to do! Luckily, I’m not the only one who works on this website, so I wrote an email to my friend and asked him to help me with the refactoring process.

Here’s the email in its entirety:

Ok, this email is quite lengthy, and it might look overwhelmingly complicated, but trust me, it’s not. Just read this entire email from start to finish before you start doing anything, and you’ll see that it’s not complicated (just time-consuming).

INTRODUCTION

In 2.0, instead of executing raw SQL statements, we’re using an ORM framework to handle the query execution. There are several benefits to this approach which I won’t go over here, but let’s just say that the benefits are significant enough that they warrant a total re-write of the way we’re executing our queries.

The ORM framework we’ve chosen for 2.0 is called Doctrine (http://www.doctrine-project.org/). This is the thing I was telling you about that generated all of our database models for us based on the new 2.0 database that you created, which is one of the main reasons we chose it over other ORM frameworks. The other reason is that it integrates seamlessly into Zend Framework, which is the PHP framework that 2.0 will be built on top of. There are bits of Zend Framework sprinkled over the current version of the game, but this time around we’re going all in so that we can harness all of the power that Zend Framework has to offer.

But more about that later.

CONVERSION PLAN FOR 2.0

The key to our success lies in the order in which we convert the various sections of the game. Here’s a brief outline of that order:

  1. Convert SQL queries
  2. Football Server
  3. Registration/Login
  4. Join/Create League
  5. Auction
  6. League Screens
  7. Everything else

The first thing we need to do is convert the queries, so for this assignment, you don’t have to think about anything other than converting queries. Don’t think about game logic or how we can improve the game while we’re converting the queries. Just think about converting the queries. Treat them as isolated entities. You’ll see what I mean in a minute.

The attached ZIP file contains all the files you’ll need for this assignment. If you haven’t already, go ahead and unzip the file and familiarize yourself with the files.

The “private” folder contains all of the files that you should be familiar with from the current game - with the only notable exception being that the Football Server class has been renamed and extracted to the root.

The “doctrine-models” folder contains all of the new models that we’ll be using in 2.0. Inside this folder is another folder called “generated” which contains all of the models that Doctrine created for us using the 2.0 database. You don’t actually have to worry about the “generated” folder - I just included it so you could have a look - in fact, you should probably delete it before you start the assignment.

THE ASSIGNMENT

There are 4 different types of queries: SELECT, INSERT, UPDATE, and DELETE. I’ve already converted most of the UPDATE queries. Your assignment is to convert the INSERT and DELETE queries. (After I’ve converted the last of the UDPATE queries, I’ll start converting the SELECT queries, and hopefully I’ll have them finished around the same time as you finish the INSERT and DELETE queries.)

DELETE QUERIES

You should start with the DELETE queries because they’re the easiest to convert, and they’ll help you get familiar with DQL (Doctrine Query Language), which is what we’ll be using to create the new queries.

I’ve already converted a couple DELETE queries so you can use them as an example:

Open up “FootballServer.php” and scoll all the way down to the bottom of the class and you’ll see one of the DELETE queries I converted. The old query has been commented out (when you’re converting the queries, you should delete the old query. I just commented this one out so you could see what’s been replaced with what.)

Immediately below the old query is a call to a static function, which contains the new query. Open up “doctrine-models/

TblAuctiontemp.php” so you can see the new query.

First of all, the new query is located in a static function within the model of the database table it’s referencing. In this case, since we’re deleting from “tbl_auctiontemp”, the static function is placed inside “TblAuctiontemp.php”. If we were deleting from “tbl_leagues”, then we would’ve created a static function inside “TblLeagues.php”. (Try to name the static functions according to what the individual query is actually doing. And be as verbose as you need to be - we can always re-factor the names later on.)

If you look inside the deleteLeagueAuctionTempValues() function, you’ll see the new query, and as you can see, the new query looks pretty straight-forward. Yeah, the syntax is new, but if you look at it, you can see what it’s doing:

//Setup query.
$objQuery = Doctrine_Query::create();

This creates an instance of the Doctrine query object. (All of your DELETE queries should start like this.)

$objQuery->delete(’Auctiontemp’);

Here, we’re telling Doctrine which table to delete from. Notice that we’re not passing it the exact name of the table. The table name we’re deleting from is “tbl_auctiontemp”, but Doctrine doesn’t use the table names directly. We pass it “Auctiontemp” instead because that’s the name of the “component” that Doctrine has mapped to the table. Don’t worry too much about that - just remember to remove the “tbl_” bit from the table name and capitalize the first letter (and only the first letter) of the component.

$objQuery->where(’intLeagueId = ?’, $intLeagueId);

We use the where() method to tell Doctrine which records to delete. Notice the question mark. Instead of using fnAddSlashes(), we use the question mark, and then Doctrine replaces the question mark with the value of $intLeagueId.

$objQuery->limit(1);

We can also use the limit() method to tell Doctrine to stop executing the query after it’s deleted the record. Be careful when you’re doing your queries… if the old query doesn’t have a LIMIT clause, then make sure you don’t use the limit() method in the new query. And vice versa… if the old query does have a LIMIT clause, then don’t forget to use the limit() method.

//Execute query.
$objQuery->execute();

And finally, we tell Doctrine to execute the query we’ve just built.

So that’s what the new query looks like. Now if you go back to “FootballServer.php”, you can see what we’ve done. Basically, we moved the old query into a static function, and now instead of executing that query in FootballServer.php, we’re just calling the static function, making sure to pass in any variables that the new query might need (in this case, $intLeagueId). Be careful when passing parameters… sometimes it’s a regular variable like $intLeagueId, and other times it’s a member variable, like $this->intLeagueId. Other times, you might want to pass an array to the function instead of multiple paramters. I’ll show you an example of this approach in the INSERT QUERIES section.

I’ve done another example to illustrate how you add multiple where() methods. Open up “private\views\viewPlayPercentages.php” and scroll down to line 766. You should see the old query which has been commented out. Notice that it contains references to two variables. Now look right below the old query and see how we’re passing two variables to the static function.

Now if you open “doctrine-models\TblDefensiveplaypercentages.php”, you can see what we’ve done here. Firstly, we’re passing it two variables instead of one, and then we’re also using two where() methods in the new query. Notice the second where() method. It’s actually called “andWhere()”.

(There’s also another method called “orWhere()” which should be pretty self-explanatory when it’s used.)

If you encounter a query which references a “dynamic” table (you can see an example of a dynamic table in “private\views\viewFormationPercentages.php” around line 866. Notice how the table name is actually a variable? Well, don’t worry about converting those unless you think you can maintain all the logic involved. If you’re unsure, just leave it and I’ll convert it later.

Also, here’s a link to the reference manual for DELETE queries:

http://www.doctrine-project.org/documentation/manual/1_1/en/dql-doctrine-query-language#delete-queries

INSERT QUERIES

INSERT queries are a bit different. Instead of building a “query”, you’re creating an object/record and then “saving” it to the database. I’ve also done an INSERT example to show you how it’s done:

First, open up “FootballServer.php” and scroll down to line 4483 to see the old query. Immediately below the old query is the familiar call to the static function. But notice how we’re passing an array to this one instead multiple variables? You’ll see why we do it that way in a minute.

Now open up “doctrine-models\TblLeaguefixtures.php” and take a look at the first static function. It only takes one array as a parameter to avoid having a shit-load of parameters. Then, inside the static function we use the values of the array to create the query/object/record thingy:

//Setup query.
$objQuery = new TblLeaguefixtures();

Create a new instance of “tbl_leaguefixtures”. Notice how we’re using the full camel-cased name of the Doctrine component.

$objQuery['intLeagueId'] = $arrData['intLeagueId'];
$objQuery['intSeason'] = $arrData['intSeason'];
$objQuery['intWeek'] = $arrData['intWeek'];
$objQuery['intHomeUserId'] = $arrData['intHomeUserId'];
$objQuery['intAwayUserId'] = $arrData['intAwayUserId'];
$objQuery['datSimulationDate'] = $arrData['datSimulationDate'];
$objQuery['booSimulated'] = $arrData['booSimulated'];
$objQuery['booRegularSeason'] = $arrData['booRegularSeason'];

Use the values of the array to tell Doctrine what values to insert into each column.

//Execute query.
$objQuery->save();

And finally, we execute the query (a little differently than how we executed the INSERT query, but more or less the same sort of syntax.)

If you come across any INSERT queries that look too complicated, again, don’t worry about them. I’ll sort those out later. If you want to give the harder ones a go though, feel free - I’ll be quickly skimming over everything you’ve done to make sure everything’s alright, so don’t worry about messing anything up.

To help you with the INSERT queries, take a look at the following link for reference:

http://www.doctrine-project.org/documentation/manual/1_1/en/working-with-models#dealing-with-relations

CONCLUSION

So that’s your assignment. I hope it makes sense. I know it’s quite different to the way you’re used to seeing the queries, but hopefully the examples I’ve shown you and the links to the reference manual will get you on the right track.

The best thing to do is create a project in Komodo (or whatever IDE you’re using) and do a global search for “DELETE FROM” for the DELETE queries and a global search for “INSERT I” for the INSERT queries. Then go through each of them one-by-one.

If you have any questions about anything, just drop me an email or find me online.

I’ll have the rest of the UPDATE queries done this weekend, and hopefully a good chunk of the SELECT queries as well. Once all the queries have been converted, it’ll be so easy to get the server up and running so we can start generating leagues and simulating games. And that’s a HUGE step forward to launching 2.0 - everything after this is cake. :)

Thanks man - and good luck!!!

Jeremy

Captain’s Log(1) :: Introducing the D4 Framework

Wednesday, May 27th, 2009
http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/digg_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/reddit_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/dzone_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/stumbleupon_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/delicious_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/blinklist_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/technorati_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/google_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/myspace_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/facebook_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/yahoobuzz_32.png http://www.d4online.com/blog/wp-content/plugins/sociofluid/images/twitter_32.png

PROLOGUE

Welcome to the first installment of Captain’s Log(), the “techie blog” where you get to read about what the web developers & programmers here at D4 are working on and thinking about. I’m Jeremy (a.k.a. “The Captain”), and I’ll be your resident techie for this series of technical blogs.

Let’s get right into it, shall we?

INTRODUCTION TO FRAMEWORKS

Frameworks.

It seems like all the web programming languages these days have a framework: Ruby has Ruby on Rails. PHP has Cake, Symfony, CodeIgniter and Zend Framework. ASP has ASP.NET. Flash has the ActionScript Foundry. Java has Spring and JSF. Javascript has jQuery, Dojo, YUI and a few others. Even Python has a framework!!!

But what is a framework and why are they so popular?

DEFINITION OF A FRAMEWORK AND ITS BENEFITS

According to Wikipedia, a framework is “an abstraction in which common code providing generic functionality can be selectively overridden or specialized by user code providing specific functionality.”

In other words, frameworks are foundations of code upon which we build web applications and websites. They’re usually open-source, which means that they’ve been rigorously tested by thousands of developers from all over the world; and in many cases, they have huge corporations behind them, which means that they’ve been written by some of the industry’s leading web developers.

So in a nutshell, frameworks allow developers to avoid having to re-invent the wheel for each web application they develop, which is great - not only for big development teams, but also for small development teams who find themselves in the position of being flooded with work.

Which, fortunately, is the position we’re currently in, here at D4.

WHAT’S A CAPTAIN TO DO?

When I took the role of Senior Web Developer back in December, I quickly realized that things were changing at D4. Previously, the majority of our projects were exclusively for graphic design or print design, with the occasional website here and there. But today, it seems that most of our projects include some form of web development - whether it’s a website, e-commerce website, content management system, image gallery, etc.

Those kinds of projects usually require a large team of developers, but since the development team at D4 is quite small, we needed to come up with a way to get these projects out the door - and more importantly - a way to keep the quality of web development at the same high level as the quality of D4 design quality.

Definitely not an easy task!

INTRODUCING THE D4 FRAMEWORK

We’re still getting a high volume of projects in these days, which is somewhat surprising given the current economical climate, but not really that surprising because D4 is one of the best design agencies in the country.

In order to deliver these projects on time, we’ve decided to extend two of the best web development frameworks out there. The PHP side of the “D4 Framework” is built on top of Zend Framework and the JavaScript/CSS side is built on top of YUI.

By leveraging the benefits of Zend Framework and YUI and extending them to suit our own needs, we’re able to develop enterprise-level websites and applications in a fraction of the time it would take to build them entirely from scratch. Shorter development times mean that we can quote shorter timescales to our clients, which means we can offer the same high-quality solutions at more competitive rates.

And in the current economic climate, that makes for some truly satisfied clients.

CONCLUSION

I hope you’ve enjoyed the first installment of the Capatin’s Log(). Next week, I’ll be spilling the beans on a very exciting project we’re currently working on, so be sure to keep checking back.