CakePHP + GraphViz = making sense of a numerous models

NOTE: THIS IS VERY MUCH OUTDATED! Read about the update or go directly to GitHub repository for the new version.


I have a task at hand.  I have to re-introduce myself to a rather large codebase.  It’s a project that migrated to CakePHP a couple of years ago and haven’t seen since.  There was a whole team of people working on it sense then, and now I need to make sense of all those changes that were done and help reorganize and refactor them a bit.  When I looked into CakePHP’s models/ folder, I was surprised to find 50+ models there.  Each and every one of them links to other models.  And documentation is practically non-existing.  How do I go about it?  I hack up a little script to help me out.

There is a really elegant and beautiful tool for graphing things – GraphViz.  If you haven’t heard of it, you need to drop whatever is that you are doing and familiarize yourself with GraphViz.  Right now.  Right.  This. Second.  You are missing out a whole universe until you do so.  I’ll wait.

Now that you are back, I just want to mention a very slick tool, which is a part of GraphViz package – dot.  It is a simple language in which you can describe graphs.  Sort of like “A goes to B, which goes to C”.   You specify your graph in a very human readable format in a text file, and then dot will transform that text file into an image format of your choice (PNG, JPEG, GIF, etc).  The primary beauty of this is that those text files can be generated automatically by using pretty much any programming language.

So here is what I did.  I assumed the following:

  1. Project documentation should be in app/docs/ folder.  That’s where I’ll put the script and that’s where it will generate the dot configuration, dot later will generate the graph of all my models and their relationships.
  2. Main project application folder is app/.  Models are stored in app/models/ folder.
  3. Project can have a number of plugins, which can have their own models, which I still want to know about.  Plugins are in app/plugins/ and if plugin xyz has models, they are stored in app/plugins/xyz/models.
  4. My project is under version control.  Specifically I use Subversion, but it’s easy to adjust the script to support other systems.
  5. I can get current project revision by running a command in shell.  For Subversion that is /usr/bin/svnversion.

I probably assumed a whole bunch of other things, but you can get an idea of how simple the setup is from the above ones.

Here is how I generate a graph of all models and their dependencies:

cd app/docs/
php -f graph.php >
dot -Tpng > graph.png

Obviously, I can’t show you the full graph from that system (it’s not open source, it’s not mine, and it will drive you insane in a matter of seconds), but here is how a small part of that image looks like.

There is a different colour for each type of model relationship ($belongsTo, $hasMany, and $hasAndBelongsToMany). Each model folder is in a separate sub-graph cluster. There is a legend graph on the image. The current time stamp and version control revision are also imposed on the image for easier referencing.

And here is the source for the graph.php script. Feel free to modify any way you like. If you spot any major bugs or better ways of doing things, please let me know in the comments.

Continue reading “CakePHP + GraphViz = making sense of a numerous models”

CakePHP : Building factories with models and behaviors

CakePHP is a wonderful framework.   Recently I proved it to myself once again (not that I need much of that proof anyway).  The problem that we had at work was a whole lot of code in once place and no obvious way of how to break that code into smaller, more manageable pieces.  MVC is a fine architecture, but it wasn’t obvious to me how to apply it to larger projects.

In our particular case, we happen to have several data types, which are very similar to each other, yet should be treated differently.  Two examples are:

  1. Client account registrations.   Our application supports different types of accounts and each type has its own processing, forms, validations, etc.  However, each type of account is still an account registration.
  2. Financial transactions.  Our clients can send us money via a number of payment methods – credit cards, PayPal, bank wires, etc.  Each type of the transaction has its own processing, forms, validations, etc.  However, each type of the transaction is still a financial transaction of money coming in.

Having a separate model for each type of account or for each type of transaction seems excessive.  There are differences between each type, but not enough to justify a separate model.  Having a single model though means that it’ll continue to grow with each and every difference that needs to be coded in.  Something like a class factory design pattern would solve the problem nicely, but the question is how to fit it into an existing MVC architecture.  Read the rest of this post for a demonstration.

Continue reading “CakePHP : Building factories with models and behaviors”

Enforcing coding styles in PHP

I came across a plugin for CakePHP which helps to check if the certain code follows CakePHP coding style.  While I haven’t tried it, I think the better way is to utilize CodeSniffer.  As per PHP_CodeSniffer PEAR page:

PHP_CodeSniffer tokenises PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.

Which basically means that PHP_CodeSniffer is a generic tool for validating your code.  You can use for CakePHP, WordPress, or any other PHP project that you are working on.  The best part is that you can create your own set of rules regarding coding style and then make sure that your team follows it. If you don’t care that much for your own rules, then you can use one of the many existing rulesets.  Some of these come together with CodeSniffer package, others are available on the Web.

Setting up CodeSniffer for my team at work has been a long lasting TODO item, however it looks like I will be able to start working on this next week.  Once it created, tested, and everyone is happy with it, we’ll have it in the pre-commit hook in our Subversion repository.  This way, we will prevent commits of any code that does not follow our rules.  Of course, I plan to only run CodeSniffer against the code that we wrote in-house.  There is no need to re-format all the third-party code just for the sake of it.  Plus, we are rarely doing any modifications of the third-party code at all.

Toolbox : WordPress, CakePHP, SugarCRM, RT

Over the last couple of years I’ve been working a lot with these four applications – WordPress, CakePHP, SugarCRM, and RT.  Each of these is beautiful in its own way.  Each of these tools is an Open Source Software. Each of these tools has a large community. Each of these tools has a free and commercial support and development. Each of these can be used in a number of ways to solve a whole range of problems.  Let me briefly introduce each one of them.

Continue reading “Toolbox : WordPress, CakePHP, SugarCRM, RT”