With the maturing of PHP, and the final inclusion of deconstructors in the up and coming PHP 5, I’ve opted to finally get rid of some of my old cruft, and start making it OOP.

This code is not the world’s best example, but one of the first things I’ve done is rewritten the SQL database shim; this tricky little bugger allows me to account for the differences in SQL layers within PHP. Currently, it supports MySQL and PostgreSQL (it supported DBX, but I’m going to rewrite it for SQLite shortly).

What’s the difference? Quite a bit. The abstraction, with a bit of logic, allows for several simutaneous connections without fear of ‘treading on toes’ as dbshim was initally written to manage the database connection IDs by itself, however, this logic was not introduced until the move to OOP.

Find below a rather icky (elder) version from my intial revisions of dbshim:

function my_db_connect() { global $mysqlindex, $mydbhost, $mydbusername, $mydbpassword, $mydbname, $mydbtype; if ($mydbtype "mysql") { $mysqlindex = mysql_connect($dbhost, $dbuser, $dbpass) or die("Unable to connect to server."); mysql_select_db($dbname) or die("Unable to select database."); } elseif ($mydbtype “pgsql”) { $mysqlindex = pg_connect(“host=$dbhost dbname=$dbname user=$dbuser password=$dbpass”); } elseif ($dbtype == “dbx”) { // eventually, we’ll have to do SOMETHING, I think } }

This would be called by:

my_db_connect();

It would happily usurp global variables, which were only available to dbshim, but were quite bad, regardless.

Rewritten in OOP, it looks like this: class rollatorDB { function rollatorDB($dbhost, $dbuser, $dbpass, $dbname, $dbtype) { $this->mydbtype = $dbtype; switch ($this->mydbtype) { case “mysql”: $this->mysqlindex = mysql_connect($dbhost, $dbuser, $dbpass) or $this->error(“Unable to connect to server.”); mysql_select_db($dbname, $this->mysqlindex) or $this->error(“Unable to select database.”); break; case “pgsql”: $this->mysqlindex = pg_connect(“host=$dbhost dbname=$dbname user=$dbuser password=$dbpass”); break; default: $this->error(“Unable to connect: Unsupported DBType given!”); } } /* Other functions follow… */ }

As you can see, I switched to, er, switch statements, and have added an internal error system to this shim, so it won’t explictly call functions outside of itself, which is considered to be bad.

The new functionale is called as such:

require ‘rollatorDB.php’;

$myDB = new rollatorDB(”$mydbhost”, ”$mydbuser”, ”$mydbpass”, ”$mydbname”, ”$mydbtype”);

It’s different. I’ll give it that.

Where I used to use $result = my_db_query(“SELECT foo FROM bar WHERE quux=’baz’”); , I’ll now be using $result = $myDB->my_db_query(“SELECT foo FROM bar WHERE quux=’baz’”); Update: Now, well, I’ll actually be using $result = $myDB->dbQuery(“SELECT foo FROM bar WHERE quux=’baz’”);

It’s nice, since I can have several instances, if need be, with no global variable pollution.

The code is getting tighter, despite the silliness above; and by using switch statements, it’s not only more legible, but fairly trivial to add support for future databases.

Update: Since taking the plunge, I’ve rewritten the whole thing, as you can see for yourself, and even converted the elder style underscores to studlyCaps. ;)

It’s been coming down the pike.

I’ve been well aware of how my tools have become widely utilized. This has become a bit of a problem, as my excellent virtualhost provider allows a total of five gigs of transfer a month. Not so bad?

Well, since several of my tools have hit VersionTracker, I’ve been doing an average of a gig’s worth of traffic a day. This, as they say in the business, is not good.

I had to find a way to distribute this influx.

I run several services, as well as my personal website – not only do they have quite a bit of space by comparison (the majority of my traffic and storage there is SQL based) – they rarely come near their bandwidth utilization.

I hacked up support in my filemanager to allow for mirror sites to be listed in my global configuration, then opted to expand it after I had the initial frameworks laid out.

My initial revision allowed for a single mirror – it would continue to update my local download counter (as it should), for any file downloaded, then “hand off” the request to the sister site.

In an effort to increase my functionale, I then created a pseudo-random ‘site chooser’, entirely transparent to the client, which makes an educated guess as to which of my mirrors to use.

Hopefully this will save me from paying a fortune for my bandwidth, and be able to provide end users with the tools they seek!

Thanks to bug reports from users of little endian machines, I was able to isolate the issue where MyPasswordSafe might have trouble loading an existing keychain.

I’ve patched it up to read and write little-endian files natively, so you should have no issues utilizing existing keys with other systems – please note that this means any keys created with my initial port of MyPasswordSafe are now incompatible!

You can download the updated version from my software page.

I’m still working on streamlining this latest revision of Rollator; it’s at least 4x faster than prior versions (in realtime testing), due to massive rewrites of the underlying logic, and condensing functions.

Those of you three people who actually read these articles might notice that I’ve transitioned into proper table bullets for the ‘left tables’ on the front page, as well as with the integrated search functions.

I’ve removed the ‘last month’ and ‘next month’ tabs from the calendar at the top of the page; to much chagrin – It was a fun thing to tab about and see how active I’ve been over various months, but it was using up yet more precious real estate upon the screen.

I’ve added a few other customizations and optimizations; I’m thinking of creating sub-trees, thus breaking up my software page even further, by OS, type of application, et al.

All in all, I’m quite happy how things are turning out; Rollator is roughly 140k with the following existing functionale in my current ‘unreleased’ revision:

  • It’s simple. It’s quite capable for users of all technical levels, from general blogging to ‘power coders’, with support for inline PHP functionale.
  • Keen Editing Interface. Featuring an (optional) WSYISWG editor, easily browsable entry, file upload and flatfile editor, etc..
  • Support for XML-RPC: Supports WebLogs and Blo.gs XML-RPC.
  • It’s entirely dynamic. You don’t need to constantly wait while it regenerates pages. Caching is dynamically managed, so you don’t need to worry about it when publishing your weblog. Optional advanced URL rewriting rules are available to make everything pretty.
  • Multiple Databases. With my trivial abstraction layer, Rollator supports MySQL, PostgreSQL and (will support) SQLlite databases.
  • Integrated “QuickLogs” and “Music” blogging. Trvial API, which is easily used from virtually all platforms allow users to log their musical selections, bookmark web pages, et al.
  • File Manager. Rollator touts a full external file manager for software engineers, keeping statistics of downloads, managing files and their signatures, and optionally run-time testing checksums to ensure files match stored signatures.
  • Multiple Users. Multiple users can edit and administrate the weblog.
  • Standards Compliant. Rollator generates XHTML 1.1, CSS 2.0, and RSS 2.0 feeds.

You can see that I’ve put quite a bit of time into this. I’m still working diligently in regards to cleaning up the entire structure and making it a full ‘upload and use’ system.

One of the primary internal functional changes to Rollator, besides becoming a CMS unto it’s own right – from it’s old blog days, is to tout full administrative functionality; with not only a localized ‘root’, or ‘Administration’ user, but to offer subusers various access to editing and modifications, et al.

After re-implementing my cookie logic to use PHP sessions instead, I figured I might do a bit of cleanup of the backend interface; it’s quite usable, as you can see in this elder version, but lacks a bit of refining polish.

One of the simple changes rolled into my existing system uses quite a bit of my initally-planned functionale. This is the ability to understand idling users; or people who login and neglect to post, or logout of the interface for a specific amount of time. Heck, we’ve all done it.

After implementing my idlecheck system, I figured it’d be much more logical and easier on the mind to give the user feedback as to various aspects of this. One of these features is my Administrative Toolbar, present atop of every internal functionale; it provides information as to what has occured, based upon what the user has entered.

One of these is, ta-da the display of this idle time. It’s quite trivial, and fairly unnecessary, as Rollator will, in plain english, tell the user if it logs them out, and why.

This data is stored as a numeric, which is the offset since the last point of activity, and the current time. I store this as a number of seconds, both for the ‘idle since’ numeric, and the ‘overall time’. Getting deeper into this logic is beyond the scope of this article.

However, I created a simple function I call prettytime() which will take an argument as a number of seconds, and convert it to a number of minutes and seconds, outputting this as a rather legable, human friendly string.

It’s a bit tight, and not horribly commented, but quite easy to get the gist of:

function prettytime($time) { // Returns an arbitrary pretty date of minutes and seconds, // assumes strings are in seconds. if (is_numeric($time)) { // Let’s get this messy math out of the way $minutes = floor(round(($time / 60) , 2)); $seconds = $time – ($minutes * 60); $string = ($minutes != “0”) ? ”$minutes minute” : “”; $string .= ($minutes > “1”) ? “s” : “”; if ($minutes != “0” && $seconds != “0”) $string .= ”, ”; $string .= ($seconds != “0”) ? ”$seconds second” : “”; $string .= ($seconds > “1”) ? “s” : “”; return $string; } }

It’s pretty simple in nature, and there’s just a few things I’ve done to make it nicer. If either of these (second, minute) are above 1, it will append an ’s’, so you will get data such as 2 minutes, 1 second, and 14 seconds, respectively.

Hope it helps you out.