Recently Modified Files
I’ve been looking for awhile now a Unix command to print out the name of files that have been modified during the past n days. A command like this would be useful when I’m syncing files from our dev server to our production server. And thanks to this post I’ve finally found it:
find /<dir_name> -mtime -<n> -print
Where dir_name is the name of the directory you want to check and n is the number of days.
However I’m still on the outlook for an automated solution…
January 1st 1900
So today while I was testing I noticed that dates of 1900-01-01 were being displayed as today’s date. I figured it had to do something with Smarty’s date handling (in particular the date_format modifier and the html_select_date plugin - I use those two everywhere). Initially I thought it had to do with something about pre 1970 dates and Unix timestamps but then I tried some pre 1970 dates and they worked as expected.
Since I knew that the date_format modifier uses PHP’s strototime() function internally I looked up the documentation. That’s when I noticed this ‘note’:
Note: The valid range of a timestamp is typically from Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT. (These are the dates that correspond to the minimum and maximum values for a 32-bit signed integer.)
So that explained why pre-1970 dates were working but not something like 1900-01-01 itself.
And as it turns out whenever Smarty processes a date, it converts it into a Unix timestamp. If the timestamp fails (as in 1900-01-01) it defaults to today’s date:
$time = strtotime($string);
if ($time == -1 || $time === false) {
// strtotime() was not able to parse $string, use "now":
$time = time();
}
I thought about modifying the Smarty plugin but I still felt pretty guilty about my previous hack(!).
I vaguely remembered something about PHP having some kind of new DateTime class and after reading the docs I figured it would be benficial to use DateTime instances. The big selling points were a larger timestamp range and its format() function which formats the date automatically. Which meant that I no longer needed to use Smarty’s format_date modifer - and I no longer had to rely on PHP’s ridiculous date/time functions.
So I converted all dates to DateTime instances and I thought all is good in the world. But during the first test case I see my beloved 500 page and this message in the logs:
Warning: DateTime::format() [datetime.format]: The DateTime object has not been correctly initialized by its constructon
WTF does that mean? Google answered that for me which led to this little tidbit:
Note: It is not possible to serialize PHP built-in objects.
Some of my objects that were using DateTime instances were being stored in session (ie. being serialized/unserailized) and I guess that’s why I was getting the above warning.
So now I’m thinking ‘What kind of ridiculous hack can I come up with to overcome this?’ And here my non existent readers is that ridiculous hack:
$this->date; // a 'date string' formatted as YYYY-MM-DD
function getDate()
{
return new DateTime($this->date);
}
function setDate($date)
{
$this->date = $date->format('Y-m-d');
}
So basically my objects internally are storing the date as a string (YYYY-MM-DD) but its getters and setters are returning DateTime instances. I’m sure this violates all kinds of best practices but whatever it works.
An Interview
So What’s Been Troubling You These Past Few Days?
I’ve been writing a sh*tload of Javascript for The Project lately. And I’m sick and tired of wondering why that <div> shows up in one browser and not in another.
Why Don’t You Try Using One Of Those Javascript Framework That Are All The Rage Nowadays?
Because I like having full control over my Javascript. It makes me feel powerful! It makes me feel like a man! But these last few days have succeeded in breaking me. It’s time to learn a Javascript framework.
So Have You Picked One?
JQuery
Why JQuery?
Because Coding Horror told me to.
What Did You Think JQuery Was Before You Started Learning It?
I thought JQuery (and Prototype, DOJO, etc. etc.) just provided you a way of not typing something like ‘document.getElementById‘ all the time. Seriously.
What Do You Love Most About Learning JQuery?
It makes me not care about whether that ajax call will work across browsers. And the fact that it uses $ everywhere. Much like PHP. Now when I switch between PHP and Javascript files I don’t get that different-syntax jarring effect that give me headaches.
What Do You Hate Most About Learning JQuery?
It’s like trying to learn a new syntax. And the fact that 99.9% of the JQuery examples out there think that chaining on one line is the sh*ts. It’s not.
What The One Thing That Impresses You Most About JQuery?
The fact that it has a trim() function!
Seriously?
Hey every time I create a Javascript file I’m still including that trim utility that I wrote a hundred years ago. It’s nice to have an in built one.
So The #1 Reason To Use JQuery… Because It Has A Trim Function?
Yes. Definitely.
States And Provinces
Latest task: The Project has a bunch of address forms which needed this change:
- If the selected country is either Australia, Canada, or the United States, hide the state text box, load (from an external file) the appropriate set of provinces / states, populate and show the state combo box
- Otherwise, hide the state combo box and show the state text box.
So no big deal right?. I figured the ‘challenging’ part would be reading data from the external states / provinces (XML btw) file.
First off: Opening that XML file. Wouldn’t that be like Ajax without the ‘A’?
// for sake of simplicity showing only mozilla compatible code
var xmlHttp = new XHLHttpRequest();
xmlHttp.open('GET', <path_to_xml_file>, false);
var xmlDoc = xmlHttp.responseXML;
Apparently not - because the above didn’t work. After much googling I came up with this:
// for sake of simplicity showing only mozilla compatible code
var xmlDoc = document.implementation.createDocument('', 'doc', null);
xmlDoc.async = false;
xmlDoc.load(<path_to_xml_file>);
Now let’s read those states and provinces:
var countryId = 'USA'; var states = document.getElementById(countryId);
Hey… how come I’m not loading anything? Maybe it’s because I can’t use getElementsById() with non-strict XML! So I remove all the id attributes in the XML file and after much getElementsByTagName()-ing and attributes[i].nodeValue-ing I’m welcomed with this error:
Exception… “Access to restricted URI denied” code: “1012″ nsresult: “0×805303f4 (NS_ERROR_DOM_BAD_URI)”
WTF? However after seeing the word ‘restricted’ it become clear…
On our server, The Project is separated into ssl and non-ssl directories. All of the address forms are located in the ssl directory and the XML file is in the non-ssl one. Apparently a ssl page cannot load a non-ssl file because of security reasons(?). So all I had to do was move the XML file into the ssl directory.
Another Smarty Plugin Hack
The Client wanted the date select boxes of all forms defaulted to ‘January 1 1900′ as opposed to the current date that I implemented. The only problem is that Smarty’s html_select_date defaults to the current date when the time parameter is null (which is the case sometimes). And I’m not very comfortable forcing the time parameter to ‘1900-01-01′ in my controller scripts.
I figured I could somehow modify the html_select_date plugin and as it turns out it wasn’t so hard. All I did was force the plugin to default to ‘1900-01-01′ and add an optional parameter (default_time) to the cases when I wanted the plugin to default to some other date.
// use smarty_make_timestamp to get an unix timestamp and
// strftime to make yyyy-mm-dd
if (isset($params['default_time']))
$time = strftime('%Y-%m-%d', smarty_make_timestamp($time));
else
$time = '1900-01-01';
So for example if I wanted the date to default to January 1 1900 I would write:
{html_select_date}
If I wanted the date to default to some other date (let’s say the current one) I would write:
{html_select_date default_time=$smarty.now}
Yes it’s a bit of a hack but whatever it works for me.