strtotime for non-US (e.g. UK) dates

16 03 2009

Not a big novelty here, but I figured I’d show you what I did.

I’m working on an application for the UK market, and we have a number of date fields in the form. The previous Indian programmer took the easy way out and used text fields in the database to store the dates. When I added some more fields, I used the appropriate date/time field type, and had to store and retreive them appropriately.

The form uses a date picker taken from HTMLGoodies.  The prior version used another script which wasn’t working well, although it allowed for named months which removed any locale convention confusions. This date picker uses numeric dates, and allows for the UK “day/month/year” convention. Getting that into (and out of) MySQL is another story.

The “out of” is easy actually. Take a date and format it:

date('m/d/Y',strtotime($date)))

Before I did that, however, I wanted to test to see if the date was empty. Using empty() didn’t work, since MySQL returns an empty date as 0000-00-00, so I made another function:

function emptyD($d){
  return ($d=='0000-00-00')?true:empty($d);
}

Using strtotime, however, misinterprets the UK date format from the user, and cannot directly create a MySQL-ready date. Using the following function, quickly found at this Polish site, reformats the date from d/m/Y to m/d/Y using regular expressions (smart!).

function strtotime_uk($str)
{
  $str = preg_replace("/^\s*([0-9]{1,2})[\/\. -]+([0-9]{1,2})[\/\. -]*([0-9]{0,4})/", "\\2/\\1/\\3", $str);
  $str = trim($str,'/');
  //echo "Converted to UK date: $str<br>";
  return strtotime($str);
}

and formated for MySQL using

date("Y-m-d H:i:s", strtotime_uk($_POST['emp1_start']))
Advertisements




How to publish your newsletter to Twitter

5 03 2009

The WHY: You want people to know what’s going on with your service/organization. That’s why you write a newsletter. But a lot of people simply feel overwhelmed by lots of promotional e-mails.
Twitter, on the other hand, is still growing as a medium for quick updates (and short URLs when something interests the Follower). For me, using my browser plugin for Twitter is like watching my SPAM box fill up, and once in a while, something non-SPAMy catches my eye, and I read on.
In my humble opinion, an unsubscribe (or “mark as SPAM”) to a newsletter should be followed up with a Follow on Twitter.

See things differently? Have other motivations? Do share below …

The HOW: Working backwards;

  1. you need to post a Tweet
  2. you need a title and a link to the full newsletter text
  3. you need a Twitter account
  4. you need an easy way to publish your newsletter online to the public

If you already know how to do this, such as if you’re sending your newsletter from a WordPress plugin, and can Tweet your posts from another plugin, then you’re all set (skip to step 6). For everyone else, here’s the simplest way I’ve found to do this.

  1. Get yourself a Twitter account. Yes, Twitter.com, what are you waiting for?
  2. Pick a unique e-mail account from a free, no sign-up service, such as steveshappynewsletter@mailinator.com or hereswhatsgoingonwithme@mailbucket.org (see those websites for more details on their service).
  3. Subscribe that e-mail address to your newsletter
  4. Any e-mail sent to those addresses can be accessed via RSS feed, such as http://www.mailinator.com/rss.jsp?email=steveshappynewsletter or http://www.mailbucket.org/hereswhatsgoingonwithme.xml (including your confirmation e-mail, if you have one)
  5. Go to twitterfeed.com, login with your OpenID, and enter your Twitter and RSS details. Now, any newsletter you send out will go out to your Followers with a link to the full e-mail text.
  6. Publicize your Twitter account, especially on your unsubscribe page

If there isn’t already a service that does this on one site, then there probably will be in about 2 weeks. Just send me 10% of the advertising revenue, ok?

UPDATE: I just tried out  Twittermail, but it doesn’t (yet) allow for HTML/Text formatting, and even the Read More page doesn’t show much more than 140 characters of the message.





Going from a Live Site to a Database

3 03 2009

We all know that it’s a web developer’s job to turn a database into a live web site (often design the database too). But what about when a client wants to take the data on a live site, and turn it into a database/data file.

  1. Stage #1 – download the site
    Retreiving the site requires planning and foresight for the next step. Using wget, my first approach was to mirror the entire site

    wget -m -w2 -x -E -k -D  "www.thesite.com" -p http://www.thesite.com

    I was greeted with a restricted message, which lead me immediately to believe that wget was violating a robots.txt or similar restriction. I added to the above command:

    -U "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6 (.NET CLR 3.5.30729)"

    which set the user agent to my browser settings.

  2. Stage #2 – prepare the files for pattern matching
    The easiest method I could imagine using was to combine all the (relevant) files into one file. I’m no Unix expert, but I was slightly familiar with cat. After some research, I combined cat with find, and later learned some xargs to make cat work for the job. But I kept running into problems, sometimes with syntax, sometimes with argument list size, and sometimes other unclear File errors.
  3. Stage #1 revisited – download a second site
    I decided to try the next site by downloading the pages directly into one file, using:

    wget -r -l inf --no-remove-listing -w2 -D "www.site2.com" http://www.site2.com -np -O site2.html -U "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6 (.NET CLR 3.5.30729)"
  4. Stage #3 – the script
    My approach was to use a simple script using regular expressions to convert the data into a CSV file. Javascript will run pretty slow, so I modified an existing PHP script for our purposes.
    I gzipped the files on my unix box, and copied them to my local Windows machine.
    After getting the right regular expression using  The Regex Coach, I pushed the data file through, but hit some problems. As it turns out, one large file, what I was trying to acheive in Stage #2, didn’t fare well with preg_match_all. It seems the function hit a limit and stopped returning results.
    The previous script was equipped to read a directory and process each file independantly. So I found a class to emulate the unix split function, dividing the huge string into smaller, tolerable files. Of course, I might have been splitting the blocks and messing with the reg. exp. So instead I split the multi-file file into single-file strings

    $ar = explode('<html', $str);

    and handled each original “file” independantly.
    Viola!

  5. Stage #2 revisited – what to do with a complete site
    Now I have a site with lots of pages in lots of directories. What to do? I tried using Windows Search/Explorer to find the relevant files from the many directories, and copy them into a single directory to be processed by our now flexible script. But Search only returned 5,000 results (I found out later the file count was closer to 70,000), and when I tried to copy/move the files into a single directory, Windows hung for a few hours, gobbled the CPU and did nothing. A quick search found me XXCOPY, which I easily installed, flattened the directories, and ran our script without a hitch.

I’m sure there are quicker ways to do it by those Unix experts, but now I have this flexible script that can operate on a number of input types fairly easily, so I’m happy.

Let me know if you’re interested in seeing this PHP script.





Unresolved: Position:absolute, MouseOut/Leave and Internet Explorer

19 02 2009

In a nutshell, my unresolved issue goes like this:

I’m trying to detect when the mouse leaves a region which is displayed on an absolute position on the page. The only problem is that IE keeps reporting that the mouse has entered the element underneath the position:absolute element, correctly firing the MouseOut event (also the MouseLeave event which I *really* want to use anyway).

For now, I’ve put in an acceptable work-around, placing an X to click, and capturing clicks on the document, so that the element disappears onclick on the X or elsewhere on the page.

P.S. the Prototype function spoofing IE’s MouseEnter and MouseLeave, located here worked very nicely. But IE’s native events seem to have problems!





Symfony ObjectHelper woes

12 02 2009

Another dreaded case of Symfony’s white-screen of death struck on a customized Admin Generator -created page for editing. I got no on-screen or logged PHP errors. I tried doing some manual echo statements to track where the problem lay, but it just got me down the wrong path. Of course, the problem only occurred on my production server, but my almost identical development server showed the pages just fine.

Finally, I had a look at the Symfony logs, and noticed where the execution stopped short – right after a partial field that I was using to provide a drop-down category select. I was using the object_select_tag function, and removing that line fixed the problem. Thankfully, that function is an elegant wrapper for the select_tag/objects_for_select functions (the latter being a wrapper for the options_for_select function), and replacing the object function with its functional equivalent made things work fine.

Debugging is tiring!
Read the rest of this entry »





Drupal 6.x Drop-down menu

10 02 2009

For the second time, I was tasked with setting-up a down-down menu in Drupal for the Primary Links. I don’t recall struggling last time, but this time it took a while until I could get it to render properly. I checked the old code, and the menu was shown using the Primary Links block. Instead of adding in blocks and doing it the same way, I thought I could make a few small adjustments to the theme’s template.php

Read the rest of this entry »





Drupal Date API woes

8 02 2009

Programming and debugging are best when the product is accompanied by decent documentation. I recently had the pleasure of debugging a custom Drupal module which involved date inputs, etc.  A feature of this module stopped working, and the PHP error logs pointed to a missing function, date_select_input. Upon investigation, I traced it to the Date module, but couldn’t find it in my version. I looked to see if we were up-to-date, and when I realized it was, I thankfully found the documentation page: Converting modules from Date API 1.x to 2.x.  Apparently, the module was updated, and the new version deprecated this function with no backwards-compatibility. Thankfully, the client wanted to use the Jscalendar (Drupal 5.X) module, already implemented elsewhere on the same page, so we just had to replace the code with a different functioanlity altogether.