Get it All

Took me basically all day to get this done, but as of this moment, is now powered by the newly-fused WordPress 3.0 installation. Whereas previous versions of WordPress were branched into WPMU and WordPress classic versions, the new version brings it all back together (very Holistic, actually!) into a single installation.

I’m going to confess that vanity made me resist this new version: WPMU was the advanced version of WordPress that made me feel cool. But given the way in which I generally use WordPress MU on this site, the new synthesized version of WordPress is probably a better choice anyway.

On a technical basis, one of the things that concerned me most was how the association between the various blogs would differ with this new installation and whether carefully-built plugins that deliver the front-page content would end up broken as a result of the upgrade. I’m not sure whether the new version introduces new methods of access, but certainly the old ways have been maintained and the transition has been fairly straight-forward as we’ve come to expect from the great folks at Automattic.

So the question now is: how does this affect my WordPress MU Function List? Are these functions still relevant and should I create an entirely different page for new stuff? I must confess that I’ve been out of the WordPress game and only just barely paying attention to the Hackers list, so perhaps tomorrow is a good day to correct that laziness on the WP front!

Another task for the near future is yet another redesign of the front page. My “Fluidity” experiment was a good one and worthwhile. But now that I’ve had a chance to see what the front page looks like on a high-resolution wide-screen monitor, it’s clear that the experiment should be brought to its swift conclusion. My blue and white pipes theme will doubtless be maintained, but I’d like to return to a fixed-width design. All in good time!!

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?”

Another post in my Development Walk-Through Series, following me through the development of my own application to share my thoughts and observations. Please consider subscribing to my feed if you find this information helpful.

Now that you’re working on your Models in Phase Two of your development process, you have a second opportunity to trim up your database. Once you start putting together CakePHP queries, it quickly becomes obvious that CakePHP will arrange your queries according to it’s own sense of MySQL rather than what you might have originally thought. This means that the database development you did in Phase One will have to be altered a bit.

But the way you put together queries is also important. For example, when assembling the [‘conditions’] array within your query, the order in which you specify the conditions is directly reflected in the way the conditions are built into the query.

Why is this important? Well for a start, because if you’re using any multi-column indexes, those indexes rely on the order of columns in the query being in the same order as they appear in the index. Without the correct order, they simply cannot be used. I don’t have any proof to back this up, but it stands to reason that this fact may point the way to another tweaking possibility: that the order of columns probably matters regardless of whether or not you use multi-column indexes.

The take away from this is that when you create queries in the CakePHP manner, it’s important to look at the resultant query and make sure it’s behaving the way you expected it to. If you can tweak the query, do it. If you cannot, it’s probably time to rethink some of your optimization strategy to better reflect the reality of the system in which you are working.

The below-linked article is an excellent example of how to use multiple databases in CakePHP, with an eye towards having a production, development and potentially, even more environments with which to work.

Easy peasy database config (Articles) | The Bakery, Everything CakePHP:

Like a lot of developers out there, I use Subversion to keep control of my code and projects, and I also use a different database for development and production. But when using Cake this can be a problem when checking out my code from development to production. Unless I edit my database.php with my production config, the production code would have problems, as it would be trying to access data from the development database.

The only thing I would add is a minor clarification to the one thing that tripped me up, abbreviated in this code snippet.
[code lang=”php” highlight=”4,8″]
var $development = array(…);
var $production = array(…);
var $test = array(…);
var $default = array();

function __construct()
$this-&gt;default = ($_SERVER[‘SERVER_ADDR’] == ‘’) ?
$this-&gt;development : $this-&gt;production;
The important thing here is that CakePHP *always* requires the “default” database entry. The purpose of having the other database arrays is to set the correct one at runtime, which as you can see, the author does by checking the IP address. He then replaces the empty “default” array with one of the desired database arrays.

In my case, I’m running both environments off the same VPS, so I’m comparing domain names. But the idea is the same.

I’m continuing to work with my CakePHP project and have run across some interesting math problems I thought I’d share that surround ratings and popularity ranking for the site.

The hypothetical new service provides a social network sensibility to local civic participation, allowing users to vote on the importance of issues and comment on them. The ranking system is a simple up-or-down voting system, held in the database as either a 1 or 0, depending on the vote.

So, being a social networking site, it is important to provide some rankings in order for people to know what’s hot and what’s not on the site. These rankings are: newest, highest rated, most popular and most active. Highest rated and most popular differ in that the highest rated issue is purely a function of the ratings system, whereas most popular needs to take into account how many people have commented. Most popular and most active differ in that most active is merely an indication of how many votes and comments a given issue has. Newest is obviously a function of time and therefore a straight-ahead dB query.

So, how to arrive at the other ratings? This seemed more obvious at first, but it got more complex as I went. I determined that the best thing to do was to get out the old spreadsheet and start laying out some numbers. Initially, I thought the highest rated function aught to be purely a count of the “yes” votes on each issue. But such a system does not take into account the power of the “no” votes. The solution was to divide the number of positive ratings by the total number of ratings. This gives you a percentage of the positive ratings, so one positive rating out of five makes an overall negative rating (20% positive), whereas one positive vote out of two is much more strongly weighted (50%).

This is not an entirely satisfactory, since a single positive vote can launch an issue to the top of the ratings board. There is also the issue of two or more pairs of ratings and positives equaling the same average, such as “4 ratings, 2 positives” and “2 ratings, 1 positive.” But since the ratings are not the only criteria, it’s acceptable to over-rate low numbers. The issue of matching averages will have to be dealt with in a sorting correction.

The next step was to determine the most popular issues. In this case, I opted to multiply the rating by the number of comments. This is a more satisfactory result overall, except that no matter how many comments an issue gets, if the rating is 0, the popularity is also 0. The solution to that is to add back in the number of comments, which has the effect of pushing up the lowest numbers without unduly affecting the higher popularity numbers.

I think I’ve gotten a decent handle on how to jiggle the numbers and get out of them what I think is most important. I’d be interested in hearing from any statistics experts or other folks with experience in this type of thing how they would change my metrics system to be more accurate.

The last few weeks have been absorbed in some freelance work for a local marketing company, which is a nice change of pace. But that also means I’ve not been able to get at my new pet project in that time, which has been a bit of a downer.

And since that new project is CakePHP driven and I’m only really learning the platform, time away from the project means knowledge lost or at least deeply buried. That makes getting back into it something of a challenge.

And indeed, I took the better part of the last two days figuring out a problem which turned out to have been rather obvious. Obvious, that is, if you know where to look. But with all that out of the way, I’m starting to make some decent progress on the project and am hoping to get something that at least looks nice by the end of the week.

Because more than one recruiter has said they want something like this to point to as a portfolio item. Everyone seems pleased with the direction I’m going in: they like what the project’s aim is. Sorry I can’t share that on this blog, but until I’ve got my domain name in place, I don’t want to screw myself.

But I really like the layout I’ve chosen for this project: very clean with big, friendly fonts to draw in the less-technical. The project is supposed to be about lowering the bar of participation in government, so it’s important not to cram too much information on any one page.

Hopefully by week’s end: a preview of my new CakePHP-powered web site!

I’d been holding off on upgrading to WPMU version 1.5.1 because I was worried that the extent of the changes from 1.3 to the new 2.5 codebase might be a bit too much for the system without some serious recoding.  Turns out, I was about half right.  And when I did finally upgrade about a week ago, it was a comedy of errors that forced my hand.

Since I’m on a web host that limits the size of my database, it has ever been a concern that I would hit the cap on my main blog.  The Tan-Tan Noodles Flickr Plugin did just that to me, since it saves all the pictures you display with the plugin as binaries in the database.  Suddenly one day, I could not post to my site and plugins seemed to be magically turning themselves off.  I thought for sure that someone had hacked into my site.

So, I opted to upgrade, hoping any security holes in 1.3 might be closed in 1.5.1.  Crazy, but again, I was panicking with a fairly high-traffic site suddenly being in limbo.  Unfortunately, I didn’t figure out the db problem till long after I’d already overwritten my old 1.3 files.  After I did the upgrade I found that my templates weren’t loading correctly.  Why should that be?

It turns out, after a long time troubleshooting, that a couple mu-plugins I’d written to bring content from other blogs to the main blog had become unusable.  I figured this out because Donncha’s post describing some of the new changes mentioned that plugins using the switch_to_blog() method might have a problem with the new caching system.  That didn’t turn out to be the problem, but since some of my code was still using another method of snagging the info (literally, concatinating “wp_1_posts” and querying the db directly!), it was this method that was causing the problem.

So a warning to you plugin writers out there: stick to the WPMU API to the best of your abilities!  I’m not entirely sure why querying the db would have caused so much grief, but when I switched to the API, I had no problems.

When I started using FireFox, I discovered something truly amazing (to me at least) in the development world: the idea of separating basic functionality from advanced usage; the idea that a program could be continually improved upon in terms of security and stability without having to add on new features and gadgets, and new gadgets could be added as desired without danger to the core application’s stability.  This was something foreign to someone accustomed to downloading the latest Microsoft updates, which always blend fixes with new features in a confusing and often problematic way.

And since working with WordPress, I’ve come to expect roughly the same thing of that platform.  Plugins can be added at will with minimal risk to the core, and the core updates periodically with new bug fixes and improvements to stability, security and performance.  That is, until 2.3 came out, then 2.5.  And perhaps more importantly, until the new development schedule came out.

WordPress 2.5 is a great new interface that improves the back end and allows us plugin developers to hack what is probably the most important bit of WordPress: the author/administrator interface.  WordPress 2.3 expanded the role of what they now refer to as “terms” and introduced tagging, which I have to admit I love.  But these are radical changes to the core with far-reaching consequences – and they piggy-backed each other in the space of maybe six months.  Its one thing to say that we developers need to keep up, but these changes drastically affect the end user experience in complex ways that are sure to leave them in the dust.

What’s more, they want the development process to be this fast.  Indeed, they skipped right over 2.4 because the changes they wanted were so radical that there wasn’t time in the release schedule to come up with a stable 2.4.  That should be some indication of just how completely crazy their schedule is.  But I haven’t seen a whole lot of talk about it.  Rather, the impetus coming from the top seems to be that WordPress needs to remain competitive and therefore has to have a fast-forward development schedule.  Their release schedule is even planned on a time-based scenario, rather than the more logical needs- or at least design-based schedule.

But now we’re stuck with a Microsoft-esque problem, in that in order to maintain the security and performance enhancements of WordPress, we must of needs also accept new feature enhancements which we may not want or need.  This is not what I’d expected of WordPress at all.

I realize that some changes need to affect the core directly.  I accept that software needs to advance itself in order to remain relevant.  But I am hoping that the folks who push the levers at Automattic rethink their insane release schedule.

I’ve just completed a new plugin, called the Titles to Tags plugin, which I’m sorta proud of. Basically, it checks the title of your post against a list of ignorable words, and then adds tags to your post automatically out of those words that did not appear on the ignore list. The idea is to automatically create a list of relevant keyword tags for your posts. The nice thing is: since I’ve learned to adopt the WordPress API, I’ve found that writing plugins often becomes a much less complex process.

For example, in this plugin, I have to add tags to a post. Obviously, I don’t want to create duplicate tags or create them incorrectly. The new tagging schema is quite complex in the database, and I don’t recommend anyone bother trying to create new tags directly. Instead, I used the wp_add_post_tags() function. This function first checks the current list of tags for the ones I want to add, then if none exist, it creates the tag automatically. This kills both birds with a single stone.

Plus, of course, if the underlying structure of WP should change – and we know it will, eventually – the API will either remain the same or be kept as vestigial, so the plugin doesn’t break because a blog owner did the responsible thing and upgraded to the current version. Another major advantage is that WordPress functions often go through rigorous standards testing and benchmarking, so by using API functions, you’re getting your best shot at creating a highly-compatible and optimized plugin.

It was with much anticipation and a fair amount of trepidation that I awoke this morning, prepared to upgrade WordPress MU to the new 1.3 version. The new version brings MU in line with the WordPress 2.3.1 codebase, including its new and complex “taxonomy” structure, while also implementing a bunch of MU-specific upgrades. I’ve been looking forward to working with the tagging concepts for a while, now, but upgrading MU is not an easy or entirely clean process.

Because unlike WordPress, you can’t just overwrite files from the old version. Well, you can occasionally, but in this instance, because there are a number of plugin files eliminated and other changes, it’s not recommended. Besides which, if you’re running an MU site with a number of users, you’re likely to find that upgrading in such a way that leaves the website open for a time comes with some complications that are probably best left avoided.

So, I can faithfully report that, if you delete all files and begin the upgrade with a clean MU installation, the upgrade actually is quite painless. I’d wondered if switching to the new taxonomy tables would make things complicated, but it doesn’t. In fact, Donncha was even nice enough to include a plugin for converting Categories to Tags site-wide, if you so chose. This all makes me feel pretty good about switching over on my main website as well.

On the other hand, there is a slight complication to switching over there which I’ve not worked out yet: the newest MU-specific addition in this release is the option to modify registration availability. You can now specify if visitors can create blogs, user accounts, or neither and you can also set it to allow only registered users to create blogs (which I presume means that visitors cannot create user accounts, otherwise that would defeat the purpose, as I’ve discovered. More on that later). This is a great addition which was desperately needed, as was the ability to hide your wp-signup.php file from search engines, thereby reducing the effectiveness of certain kinds of spam/splog attacks.

However, I’ve been using a tweak I’d developed which allowed users following a key-encoded link to create both the username and blog while providing other users only with the option to create a user name. It was a scheme meant to at least avoid spam somewhat while allowing my approved users to create the blogs they needed. It’s not100%, but it keeps the tourist spammers at bay for the most part and saves me the trouble of having to either a) create blogs for users or b) provide an extra set of instructions for creating the blog after they’ve created a username.

Well now, with this new change, all that goes away. I haven’t had the chance to check out the files that go into making this whole thing work, but I suspect my hack will not be able to live along-side the current system. In any event, I’ve also realized that my plan – cunning though it might at first have seemed – did not take into account the fact that registered users could create all the blogs they wanted. So, all someone with the time and drive would have to do was create a username and then create blogs all they wanted. Someone actually did this, though I suspect in this case that it was unintentional.

I think I’d rather have the security than the ease of administration, speaking personally, but it’s prohibitive for users starting up on my system. What I might do is edit the wpmu-functions.php to include a link back to the wp-signup.php file in the user account registration email, but I’m not sure. It figures that, after almost a month wrangling people into blogging on my network, people start suddenly all getting around to setting up their blogs on the weekend that I want to make this upgrade. This is one of those things that’s not really possible to do in a few minutes before I go to bed, so weekends are pretty much the only near-convenient time frame to do such upgrading.

Oh, yeah! And I’ll also need to upgrade my templates to include the new tagging features as well. Joy!