Get it All

I’ve discovered an interesting behavior in CakePHP that, as far as I know, is not documented in the book. I’d rather not attempt to edit the book – I’m not sure I’m right and anyway, they’ve just changed the book in some rather annoying way that I’d like to observe a bit before using – so instead I’ll just note it here for now.

The behavior in question concerns the pass array that exists in the Controller $this->params array and also the one that exists in the Router::connect function. Apparently, these two are connected in at least one very specific way. Namely: the order of elements in the Router::connect pass array overrides the order of elements in the URL model. Consider the following:



* Entry in routes.php:
array(‘controller’ =>; ‘rating_events’, ‘action’ =>; ‘index’),
array( ‘pass’ => array(‘company’, ‘location’, ‘city’),
<– Insert regular expressions here –>

In the above code, if the pass array was not set,we would expect that the pass array in $this->params[‘pass’] would follow the natural order in the URL:
array(‘ny’, ‘east_rochester’, 12);
But with the ‘pass’ array set in Router::connect, the array actually comes out like this:
array(12, ‘ny’, ‘east_rochester’);

You can therefore define the exact order of elements in that resulting params array. I can see this being handy as in the development process I’m currently going through, where the order and number of parameters passed in this way might be different from Controller to Controller, but always referring to much of the same data and using a lot of shared functions. Being able to organize the order of this array – for example, always having city and location appear in the same order and at the same numeric position – lowers the cost of processing and developing later when you don’t need to make exceptions in your code for Controller A versus Controller B.

I happened upon this when reorganizing my URL structure to try to make it universal. I couldn’t get the params[‘pass’] array to work, so I printed it out. Imagine my surprise when it was a completely different order than I expected!

For reasons I’m not entirely clear on, CakePHP developers object in general to the practice of including Models into your Componets. I suspect the problem lies in the idea that you might end up with lots and lots of associated Models within the overall framework of a given Controller, leading to bad performance. That makes some sense, but why aren’t there any directions then on how to include the Controller’s Models into the Component, when its actually quite easy to do?

I dunno. But I finally figured it out and I’m passing along the information.

The trick is using the initialize() function. I presume that CakePHP must look at all included Objects to see if this function exists, otherwise I’m not entirely sure how else it becomes a globally recognized function. Perhaps someone more knowledgeable can chime in down there in the comments thingy?

Still, here is some sample code that first includes the Controller into the Component as a reference (taken from this example in the CakePHP Book) and then takes the logical next step of including the Model (in this case, WebPriceView) into the Component as well:
// initialize: Initializing the Component, importing some needed Objects from the Controller.
public function initialize(&$controller) {
$this->controller =& $controller;
$this->WebPriceView =& $controller->WebPriceView;
It bears mentioning that this example can be extended well beyond including Models to including helpers and anything else you need from the Controller.

I’ve seen many threads on the CakePHP Google Group about how to organize files on a CakePHP installation, but many of those threads are very old and I don’t think they’re always all that relevant. Once a project gets involved, or if the project is aimed at recreating an already-complex structure, it is common to have many files of similar function that it only makes sense you would want to organize into subfolders for expedience – not to mention neatness. Recently, I’ve had cause to start trying to organize files and thought I’d share a few observations. If you find any errors in my logic or ambiguity in the way I explain things, please comment below so I can make the corrections as needed.

Controllers and Models

Probably the most convenient in terms of CakePHP’s ability to flexibly handle subdirectories are Models and Controllers. Here you have the ability to just throw files into subdirectories of the /controllers or /models folders at will and CakePHP will automatically find them at run time with no extra configuration. I have not tested folder depth: I have not see whether /controllers/deep/path works as well as /controllers/path, but certainly a single subdirectory works fine, even with files that were already created in the root directory and later moved.

Views (and Elements, and Layouts, and so on..)

With Views and Elements, subdirectories still work, but in this case the subdirectory path must be specified. If you put an element file inside /views/elements/charts/template_1.ctp, then the path relative to the /elements folder must be specified like so:
[php]<?php echo $this->element(‘charts/template_1’, $args); ?>[/php]
So, that’s pretty much all I had to add to the conversation. I hope this relatively simple blog post helps a few of you out there looking for a straight-forward answer to the question, “How do I organize my CakePHP files?”