My Blog

contains PHP and other web related content. (Sometimes there are some off topic things - don't freak out!)

Archive for January, 2009

Trac Bookmarklet: load ticket number easily

Saturday, January 31st, 2009

While communicating with other coworkers, they generally just give me a trac ticket # and not the full URL. And, as a lazy programmer, I hate typing in the full URL or loading up trac and searching the #. So, I generated this bookmarklet. Replace the url with the root path to your trac instance. Finally, create a bookmark and put the following content in it:

?View Code JAVASCRIPT
1
javascript:var url='http://domain.com/trac';var p=prompt('Ticket #?');if(p)document.location.href=url+'/ticket/'+p;

Bookmarklet: Wage Calculator

Wednesday, January 28th, 2009

While searching for employment, I realize I can’t be super picky – but my household does have needs! Because of this, I’ve developed a quick calculator / bookmarklet for the browser that I thought I’d share. It allows you to enter a yearly or hourly amount, and it shows the corresponding amounts. This tells you if that salary posting fits within your needs.

Features

  • Takes hourly or yearly wage. If amount is 200 or greater, assumes its a yearly amount.
  • Shows wages in yearly, monthly and hourly
  • Shows Gross, Company Net (assuming 25% tax bracket relatively), Independent Net (assuming 25% + 15.3% tax for medicare/social security, etc)
  • Configurable to take in other rates of tax

Here’s the bookmarklet – drag it to your book mark bar:
Calculate Wage

The UnMinified version:

?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    function bookmarklet()
    {
        var independentTax = 15.3;
        var taxBracket = 25;
        var amount = prompt('amount:');
        if (amount) {
            if (amount < 200) {
                amount *= 2080; // 40 hrs a week/ 52 weeks
            }
            var output = "Gross: $" + amount + "/yr - $" + Math.round(amount/12) + "/mo - $" + Math.round(amount/2080) + "/hr\n";
            var taxminus = amount * (taxBracket/100);
            output += "Cmp Net: $" + Math.round(amount-taxminus) + "/yr - $" + Math.round((amount-taxminus)/12) + "/mo - $" + Math.round((amount-taxminus)/2080) + "/hr\n";
            taxminus = amount * ((taxBracket+independentTax)/100);
            output += "Ind Net: $" + Math.round(amount-taxminus) + "/yr - $" + Math.round((amount-taxminus)/12) + "/mo - $" + Math.round((amount-taxminus)/2080) + "/hr";
            alert(output);
        }
    }

PHP Bitwise User Authorization

Tuesday, January 27th, 2009

After looking at the Windows model for controlling file access, I realized I could also do that for user authorization control.

The code is pretty self explanatory, but after, you’ll find a quick rundown.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
$ADMIN = 1;
$SUPERUSER = 2;
$SECTION1LEADER = 4;
$SECTION2LEADER = 8;
 
$myTestUser = $SUPERUSER + $SECTION1LEADER + $SECTION2LEADER;
 
if ($ADMIN & $myTestUser) {
    print 'got into admin<br />';
}
if ($SECTION1LEADER & $myTestUser) {
    print 'section 1<br />';
}
if ($SECTION2LEADER & $myTestUser) {
    print 'section 2<br />';
}
if ($SUPERUSER & $myTestUser) {
    print 'got into superuser<br />';
}
if ($myTestUser) {
    print 'is normal user.<br />';
}

First off, the capital lettered variables are our section permission markers. These need to expand by the power of 2. This way, our bitwise operators work out well.

Next, our test user’s permissions are the summation of all the sections/permissions that they should have access to. Its important to note that $ADMIN might be better labeled as $ADMINSECTION to not give the idea of hierarchy, but just access.

Now, when checking access to the sections, we just use the bitwise and operator. See how we use just one qualifier? This is nicer coding (because of the access additions earlier) than older code ideas:

1
2
3
4
$isADMIN = true;
if ($isADMIN || || $isSuperUser || $section1LeaderAccess) {
    print 'section 1!';
}

The one thing that I had to get over was the notion of a hierarchy in the actual values. Really, the hierarchy is business rule based, so the actual values do not matter. For example, if the $admin variable is less than the $superuser, I would think that it would mean the $admin was above. But technically, in our model, we could develop a $superadmin which could be 128 – without having to re-architect the whole system.

The only thing that keeps tripping me up is how to add a new permission, and then auto apply them to each user with so and so setting. So, for example, every $admin user should also have access to the new $section3leader variable. Is there a better way to code around this than doing an update query like this?

1
update userPermission set permission = permission+128 where permission & 1 > 0

Seems like there would be a better way to do it… any thoughts?

Eclipse PDT: Integrating Apache Bench for load testing

Friday, January 23rd, 2009

When I use an IDE, I expect for it to do everything I need for my project, from start to finish. As you may have read in earlier entries, I enjoy using Eclipse PDT. I think its time to include load testing into my arsenal of tools inside of eclipse. I’m going to focus on apache’s AB for this article.

(more…)

HTML 5 and Me – Draft 10 thoughts

Wednesday, January 21st, 2009

I thought I’d ramble on a bit about my thoughts on the HTML5 differences from HTML4 draft from working draft 10 in June 2008. You can find it – or the newest one – here: html5 diff.

I’m eagerly watching HTML5 and XHTML2 – to see who comes out victorious. I’m hoping one wins and that we get a better standard – but regardless, here are my thoughts – somewhat sporadic:

  • Open issues: longdesc and other accessbility options still open – yet there are laws (like section 508) that we’re expected to follow, but even the developers of a new specific let this slide to the end, as if its not important. Last time I checked, there was not a law making sure that the menu element was clearly marked…
  • Moving away from the SGML based doctypes, so no access to dtd needed which means can just use now to enable standards mode. Cool!
  • Symantecally, leaps and bounds forwards with asides, headers, footers, nav, article, figure, etc.
  • I am Concerned that browsers will take more styling in on these items though. For example, note that a select option is styled differently in Safari versus firefox.
  • Added embed, so hopefully a lot less of nesting object and embed to just show a piece of content.
  • Little confused by datagrid – is it used in conjunction with table?
  • How is datalist not just a different version of select?
  • event-source seems kinda cool – like you would be able to use it notify users of batch jobs finishing on the interface.
  • Input has new type attributes – like datetime. It is suggested that the browser will be able to provide a calendar, but will that be a floating one? It would be horrible if they decided to insert it into the dom right after the input box.
  • Links have ping attribute which will notify services for user tracking. However, it is suggested to give the user an opt out option. This doesn’t solve the problem at all – because people will continue to use redirects and javascript tracking then.
  • Added autofocus to input, button, textarea. This is cool because JS doesn’t need to be written to look for it on load.
  • The form attribute of input tag allows it to be used for many more than just one form. This is cool because we don’t have to write as much JS to get and share those values anymore.
  • form has a new element called data for prefilling items. I’m concerned that newer programmers may use the password field in the auto-prefill sensitive data. Probably won’t do it on purpose, but imagine writing a loop in PHP that would just generate this data, without looking to make sure that it was a password. Before you know it, the password is then cached in the page.
  • input has the new required attribute – which is cool – but how will the user experience be presented? You obviously can’t make a red border if your background is red….
  • The script has a new attribute called async – curious to hear more about that – seems to be a way to load scripts like the defer attribute.
  • Link element has a new attribute called sizes for different icon sizes. This is cool because this is helping to provide better content for the web to desktop experience – ie – saving pages with a proper sized favicon for their desktop icon.
  • iframe has sandbox feature which would allow content to display, but have no control over the existing page. This will be good to separate user input from page content.
  • The a element without a href provides a placeholder link – this is bad. I just don’t like it.
  • label’s focus has changed – it no longer will focus the control it is associated with – unless that is the OS’s major function. Don’t like that at all. I think the focus control has raised usability.
  • no frames!!! yay!!
  • Dropped acronym because of confusion with abbr – just use abbr now. *sigh*
  • Accesskey is pretty much demolished – I guess we can do this with JS libraries… just seems like a weird change.
  • Got rid of longdesc on img – good. alt is enough in my opinion.
  • name on a tag no longer exists. should use ID, which I have been doing. This is a programming change which I can see people forgetting, though.
  • Language attribute on script is gone. Wonder how that will work with js vs vbscript… or do people no longer do vbscript?
  • Cool things that were removed: attributes align, alink, link,text,vlink,background,bgcolor, etc… all of that CSS based items. The only thing that I have to work on myself is the size attribute which is now missing. I used to use it to determine how many chars would display. Need to use css width instead – which I SHOULD have been doing anyway!
  • Other API’s that are introduced include persistent storage, dragable items and registering for specific protocols for a web based application. This will be cool to see how these are implemented beside things like gears and the dragable libraries already in JS.
  • Another real cool thing – the getElementsByClassName() access for DOM based languages is now added.

Dialing Phone Numbers from a Webpage

Monday, January 19th, 2009

I’ve recently been investigating making some better mobile accessible pages for some of my projects. I’ve seen pages that allow you to dial a phone number directly from the webpage – so I thought I’d investigate…

WTAI – Mobile Protocol

The WTAI protocol is a robust set of specs to add additional functionality to web accessible phones (see more here on the OMA Technical Section). What I’m really interested in, however, is the ability to dial a phone number and add a phone number to the contacts. I’ve also heard tell that some phones do not automatically prompt the user for running this command. My moto q9c does. Just keep this in mind when using these commands for designing your pages.

Dial a Phone Number

The first number we’re going to Dial is 414.555.1212. From a usability point of view, you should also clearly label your link. The format for this link is:

wtai://wp/mc;##########

The #’s represent the phone number. See my example code:

1
<strong>Call me now: </strong><a href="wtai://wp/mc;4145551212">414.555.1212</a>

Obviously, this will make the link access the WTAI protocol dialing method.

Storing a Contact

The format for this is similar:

wtai://wp/ap;##########;XXXXXXXXXXXXXX

The #’s represent the phone number, the X’s represent the name the contact will be stored as. See my code example:

1
<a href="wtai://wp/ap;4145551212;Aaron Saray">Add Me to your contacts</a>

PHP.ini creator

Saturday, January 17th, 2009

While listening to someone complain through twitter about their MySQL conf file, I came up with a cool idea: what if I created a PHP.ini creator that would suggest changes to your php.ini file as well as generate an updated version?

Enter PHPIniCreator

As with most of my software, this is just a rough version to get the idea down on paper. I plan to update this as well as give a working example sometime in the future.
(more…)

PHP and the UUID

Wednesday, January 14th, 2009

I’ve been thinking more and more about having unique ID’s – especially with working with larger datasets – and I thought it was high time that I investigated the UUID.

The first time I ever heard about these was actually Microsoft’s implementation of the GUID in the CLSID sections of the windows registry. However, if you check out the RFC for UUID, you’ll see that’s just one of the uses and types.

My chosen UUID is V4 in PHP. I checked out the php.net/uniqid page and reviewed the comments. I still had a few questions, but settled on one example. Lets dissect this now…

UUID is Hex

So, lets make sure we fully understand our integer formats http://us2.php.net/manual/en/language.types.integer.php specifically our hexadecimal format: 0[xX][0-9a-fA-F]+ From this, we should start to think of our min and max ranges for our UUID in hex: between 0 and 0xFF…(many f’s).

The next thing I want to make sure is that PHP doesn’t convert my hex to something base 10 – so lets format it properly with the sprintf() function. Note the description of the last parameter:

x – the argument is treated as an integer and presented as a hexadecimal number (with lowercase letters).

Excellent! So, now we can deal with Hex solely – and PHP is amazing because any function that works with integers, can work with Hex – as they are just a different base of integer (math wizards are going – duh aaron… I just like being verbose… :) )

The basic format of the UUID

The basic format of the UUID – and I’m talking real basic – is:

########-####-####-############ where # is a hexadecimal number.

Of course, those nodes actually mean something (per the rfc):

UUID = time-low “-” time-mid “-” time-high-and-version “-” clock-seq-and-reserved clock-seq-low “-” node

What makes this v4?

RFC states:

The version 4 UUID is meant for generating UUIDs from truly-random or pseudo-random numbers.

The algorithm is as follows:

o Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively.

o Set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to the 4-bit version number from Section 4.1.3.

o Set all the other bits to randomly (or pseudo-randomly) chosen values.

And 4.1.3 states the binary value of this:

0 1 0 0 version 4: The randomly or pseudo-randomly generated version specified in this document.

So, what that all means is that we need to set those bits properly in each sub section after we’ve generated our random number – doesn’t sound so bad. Just use the bitwise operator.

PHP and generating the random number

Ok – first off, lets generate some random numbers with mt_rand(). The middle two sections are not a problem what so ever… we’ll use use

1
mt_rand(0, 0xffff);

However, what about the next bigger one, the 8 digit one? Well, I’m using a windows machine in 32 bit – so I did a bit of math here:

1
2
var_dump(0xffffffff);
print mt_getmaxrand();

Outputs were: 4294967295 and 2147483647 respectively, so I know we’ll have to break that up. Basically, we’ll use 2 random numbers dash one random dash one random dash three random numbers. sprintf will take care of the padding.

Ok, putting it all together

The best example of all of this – and what I used to kind of reverse-engineer for this article, was from the PHP manual, check it out:

1
2
3
4
5
sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
        mt_rand( 0, 0x0fff ) | 0x4000,
        mt_rand( 0, 0x3fff ) | 0x8000,
        mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ) );

Simple enough, proper sprintf format, all the random number generators in place, and then the bitwise operators to set the bits properly.

So – with all that said, do YOU use a different way to generate a UUID in PHP – or do you think this is the best one?

Is PHP’s __call() used when no __construct is present?

Saturday, January 10th, 2009

Simple enough question. Lets check out some test code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
class TEST
{
    public function __construct($arguments)
    {
        print "constructed with: {$arguments}";
    }
 
    public function __call($name, $arguments)
    {
        print "called {$name} with: {$arguments}";
    }
}
 
new TEST('hi');

Ran the first time, the output was:

constructed with: hi

Ran without a constructor?
BLANK. __call is not called.

Now we can all sleep at night! whew!

Localized dates in php

Tuesday, January 6th, 2009

Date formats – How time makes pretty

The PHP Date manual page has a ton of interesting features to format the date that you can display to the user. However, when you look closer at it, there are actually some really useful modifiers that will help us with our date calculations as well. For the longest time, I had just used the time() function and let the pieces fall. This was OK when the offset was similar to my own timezone – but servers change locations – and websites have global audiences. The date and gmdate functions can help with this. Both functions take an optional timestamp parameter. If you do not specify this, they’ll calculate based off of the current date. This actually becomes quite useful for our calculations… Lets jump in.

date – the date on your current server

The date() function’s default timezone is based on your server’s timezone (or php.ini’s, etc…). Regardless of where that timezone is set, it uses it to display/retrieve a localized version of the time. For example, if it were noon in GMT, and your server was in central time, if you used date() to retrieve the time, it would display a time equavalent to noon – 6 hours – so 6am. (Holy run-on sentence, batman!)

When I say displays the time equivalent, this is because of the first parameter of date’s behavior. When you review the man page, you’ll see many different ways to display the time – including some common RFC based ones.

Generally, I shy away from using date() unless I really have to. I feel it gives a bias to the output because of its timezone centric behavior.

How do we not do that??

gmdate – the date in Greenwich Mean Time

Unless you live under a rock, you know that GMT is the basis of our timezones. You are either ahead or behind them via half hours and full hours, incrementally from the distance to that location. This obviously is to balance out for the earth’s rotation – duh – enough with the 3rd grade lecture…

gmdate takes the format of the date function as well, but its default offset is ‘0′. This is especially useful if you do not send in a timestamp because it will grab the current time off the server and display it based off of the GMT (not central time for my server, perhaps eastern time for yours, etc, etc). Normally, when storing date formats, you will always be storing them in GMT to have a common base format. This function is useful because it can show you exactly, accurately what the value is that you’re storing.

So, now we know we have two functions that do rather similar things, its time to find out how to actually get them something to work with.

time – current time measured in seconds

Ok – so we have date and gmdate which take optional second parameters of a timestamp – so how do we pump them full of information besides the current time? using time() of course! Time() returns the number of seconds since 1/1/70 0:0:0 GMT. Now, since this is the # of seconds from a GMT date, to a GMT date, its a perfect candidate for both functions! Want to see a nice display of a timestamp in GMT – the local method you may have stored it in? – send it into gmdate(). Want to see what that time that really was in your timezone? use date().

Ok – display and content – we’ve got them. Now, lets tie it all together in something that is useful to the end user and website.

Date Storage, User Information, and Display

Ok, so the biggest thing to remember, lets always store our time with the time() output – this gives us a proper and accurate GMT time, no need to worry about Daylight savings, moving servers, etc. (using datestamp/timestamp formats in mysql is a topic for a full other article – at this point, we’re just using an integer to store our dates). Ok, now with our proper GMT, lets always use gmdate() to format our date as well. This way, we never accidentally introduce a timezone offset to our date. We need two other things yet, is it daylight savings time – and what is the user’s timezone.

Daylight savings time can be returned using gmdate(‘I’) – which will give 1 if daylight savings, and 0 if not. This will equate to keeping the standard offset or adding an hour to it. For example, Central time is -6 offset, but with daylight savings time active, its +1 hour – so -5 offset. 1 small caveat, you may not need to use this calculation if that user’s timezone does not have DST.

Finally, the user’s offset. You should store this with the user record. For example, when storing my record, I would expect to see -6 for central time.

A real life code example

Ok, lets see our code now in practice.

First off, Aaron comes to the website at 7:30p jan 5th, 2009 Central (1:30AM on january 6th, 2009 GMT). He posts an entry.

1
mysql_query("insert into entries (title, body, authorID, datePosted) values ('$clean_title', '$clean_body', $authorID, time());

Now, the data we see looks like this:

ID | title | body                 | authorID | datePosted
----------------------------------------------------------
1  | yay!  | I like making posts! | 12       | 1231205400

Its also important to see my user row:

ID | name  | gmtOffset
----------------------
12 | aaron | -6

Lets see some code for displaying that entry localized for when I wrote it:

1
2
3
4
5
6
7
8
9
$authorID = 12;
$entryID = 1;
$author = new Author($authorID);
$entry = new Entry($entryID);
$dst = gmdate('I') ? 3600 : 0;
$datePosted = $author->gmtOffset * 3600 + $dst + $entry->datePosted;
 
print "{$entry->title}<hr />{$entry->body}<br /><em>Posted at ";
print gmdate("M/d/Y h:i:sa", $datePosted);

Lets do a quick run down of this code:
We have the authorID and the entryID set there just for reference. We make new objects based off of them – pretty simple mock-code almost.

Next, we calculate if daylight savings time is in effect. If it is, the function returns 1 – or true. If not, 0 or false. So our ternary operator either adds an hour to the offset for DST true, or does nothing for it being off. Finally, we calculate our date posted based off of the author’s gmt offset, whether dst is active, and what the gmt time of the entry was.

  • twitter loader

Follow me on twitter: @aaronsaray

The views on this website are my own and do not reflect the opinions of my employer or clients.
Creative Commons License Home | Open Source | Book | Music | Art | Bio | Resume | Contact
My Baby