Looking into phpShop

Well, I just grabbed a small contract to tweak some stuff in an online shopping cart called phpShop. I have had quite a few run-ins with a huge variety of carts written in PHP, and by and large they have been horrible. OScart is a train-wreck, zen cart is not pretty, but is survivable. So far though, phpShop looks sharp, clean and well written. It does seem to be a bit lightweight, but most of the time thats a good thing not a bad one. As I keep going on this, I will review phpShop in more detail.

Building your own libraries

About 4 months ago I finally got the hang of building my own libraries, and having them consistently come out as useful bits of software that I found myself reusing over and over. More than anything else I stumbled across the secret to this simply as the result of some random flailing, but it’s a very good principle, and I would like to share it because I think that it’s easily adaptable.

The secret is: Write sample code first

This is not the same thing as writing test cases first, its about figuring out how you want to USE your lib, before you sit down and write the lib. you should write sample code that makes use of your library, and if it’s ugly, then you should re-write it. Try not to worry about how you are going to actually make the library do what it will have to at all, just think about writing code exactly the way you want to, in your dream scenario, when you apply the library. Go through it, are there Param’s that can be left out most of the time because 90% of the cases they will always be the same? (set rational defaults)

Now write some more sample code, this time come up with the most absurd, obtuse, edge case applications of your library. Things that it was just not meant to do properly. Write some sample code that is able to do them. Unlike the previous sample code, this does not need to be pretty, you just need to make sure that its possible. I strongly suggest making use of optional closures in order to keep yourself out of boxes.

Now go back over your ideal sample code, polish it even more. You have probably come up with some things that could be made simpler, easier and more obvious after writing the really evil edge cases.

And then finally, start writing the actual library. Figure out how to make it leap through whatever hoops you need to in order to make it fit the sample code that you have written. Try hard not to compromise your original sample code vision. If you must, make sure that you do it in a way that leaves the sample code still graceful. (sometimes it makes sense to change several things if you have to change just one)

I have found that this leaves me with two advantages for actually re-using my libraries later:
1) When I want to use them, they tend to work just how I want them to. This is a result of writing them to an ideal use case
2) I have two big lumps of sample code so I can remember how the hell I was supposed to use them without re-reading the whole body of code. Often I actually paste the simple sample into what I’m doing and then just transform it into what I need.

UI Complaint: submit buttons above the form content

I have seen numerous instances lately where a web application requires the user to look above the form or content to instigate the next step.

Examples:

  1. On bordersstores.com, a 6-page list of books has the navigation at the top (and only at the top). After you scroll through the 25 items on the page, you have to scroll back up to the top to access the links to the other pages:
    Borders bad UI example
    Hint: the links should be both above and below the content.
  2. On Wharton’s webCafé, the “OK” button is located above the login form on a toolbar with a different background color: WebCafe Bad UI Example
    Hint: it should be underneath the login form, and it should be labeled “Sign In” instead of “OK”.
  3. In Microsoft’s Windows Live, the “save” button is placed above the form in a toolbar with a different background color: Windows Live Bad UI
    Hint: put the button below the form. (At least the button is labeled appropriately.)
  4. In the latter 2 cases, one could argue that the button placement is similar to what a user would expect to find in a desktop application, such as Microsoft Word. But it isn’t a desktop application: it’s a web app, and users expect to find form/page actions at the bottom of the form.

    You could also argue, in the last case, that the user may want to make a quick edit to the name information without editing all the details. Therefore, it is more convenient to put the “Save” button at the top. That’s fine, but why not offer 2 “Save” buttons, and put one in the spot where user’s most expect it?

Checking for date-time conflicts

It seems like I’ve worked on a lot of applications lately that involve time slots: room reservation systems, appointment schedulers, and so on. One thing that tripped me (and some other developers) up at first was checking for conflicting time slots. It turns out, there are a variety of possible conflicts:

Conflicting Time Slots

There are 5 unique conflicts possible, and it seems like I’m always forgetting one.

Continue reading Checking for date-time conflicts

User Interface Issues

I just recently finished up some pretty cool feature adds to a lightweight CMS that I have built for a client. (they are happy and impressed with it, and It looks like I’m going to pick up another two jobs, where all I need to do is install the code I have written. Yey! I have been trying to get to that point for quite some time now)

One of the major reasons behind the feature upgrade was to fix some huge User Interface problems with “list management”, and they are fixed, but of course now that I’m playing with it, I have discovered that the new UI has some big issues as well. In particular, administrators now see the list exactly as it normally would be, but there are a few links next to each item that allow you to edit it, delete it, or move it up or down. It’s neat but the extra text very much breaks up the visual flow of the list in a lot of cases, and in one case is actually pretty darned hard to access.

Continue reading User Interface Issues

The Javascript Dollar Sign ($) Function

Recently, I’ve been seeing a lot of Javascript functions prefixed with a dollar sign ($) or simply named $. I thought, what sort of magical property does the dollar sign have in Javascript? What sort of esotericism had I uncovered?

The Dollar Sign Magician

I checked the O’Reilly Rhinoceros book, and found that the dollar sign has no special properties.

However, I have come to discover that dollar sign function has become the more-or-less de facto shortcut to document.getElementById(). Let’s face it, we all use document.getElementById() a lot. Not only does it take time to type, but it adds bytes to your code as well.

Here’s the version from prototype.js, which can return more than just a single element:

function $(element) {
  if (arguments.length > 1) {
    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
      elements.push($(arguments[i]));
    return elements;
  }
  if (Object.isString(element))
    element = document.getElementById(element);
  return Element.extend(element);
}

Because it has become a common shortcut to document.getElementById(), it means that various Javascript libraries should play nicely together: if the dollar sign function in one .js file is overwritten by the same dollar sign function in another .js file, everything should still work. That also means that creating your own dollar sign function that does something different is probably not a good idea.

In case you were wondering, the underscore has no special properties either. But let’s face it, $(‘myVal’) looks more like programming than _(‘myVal’).

Update 2012
By now, the most common use of the $() function is as synonym for jQuery() in the popular jQuery Javascript framework. It returns a jQuery object (or objects), which includes much more than just a reference to the DOM element. (In jQuery, you can still access the underlying DOM element using .get().)

Likewise, the Prototype code I cited above also returns more than just a reference to a DOM element, as it returns an extended version of the element. As such, Prototype and jQuery will almost certainly not work well together in the majority of cases.

schizophrenic code (It talks to itself)

The third part in the Introspective debugger code breakdown, Lets look at what happens when the code actually stops at a breakpoint…

The first chunk of code uses some globals and the backtrace to figure out if it should actually stop or just keep going I will break this down in detail later, when I go over the breakpoint code
function idbg_tick_function(){
global $idbg_stop_flag, $idbg_id, $idbg_var_spy, $idbg_last_line, $idbg_backtrace; $idbg_backtrace = debug_backtrace();
// echo ($idbg_last_line. ” ?= ” .$idbg_backtrace[0][‘line’] .” in “.$idbg_backtrace[0][‘file’].”<Br/>” );
if($idbg_stop_flag and $idbg_last_line != $idbg_backtrace[0][‘line’] and !strpos($idbg_backtrace[0][‘file’], ‘STOP.php’))
{ //echo(“</hr> idbg_tick_function START <br/>”);
Next Up We open up a tcp server on the socket of our ID, which will always be a high port. $socket = stream_socket_server(“tcp://”.$_SERVER[“REMOTE_ADDR”].”:$idbg_id”, $errno, $errstr); if (!$socket) { echo “<h1>Debugger couldn’t open socket: $errstr ($errno)<h1/>\n”;} else { because, its what they did in the example code for opening sockets, we read using a while string.I’m pretty sure that when you open the socket your thread sleeps until there is a connection to it anyway, so this is fine.When it does get a connection, we read the first 1024 bites that got sent to it, and store them in msgIn, This is going to tell us what sort of information is being looked for while ($conn = stream_socket_accept($socket)) { $msgIn = fread($conn, 1024); echo($msgIn);

The flush call is pretty important for this, it makes sure that the version of the page that the users are looking atis up to date (and not being stashed away in the buffer)

flush();For command and control we just send back a serialized version of the backtrace, and our spied variables. Much more onvariable spying in a later post (Code in RED is from a different chunk of code, its basically the other end of the conversation)
if ($msgIn == ‘cnc’){ fwrite($conn, serialize(array(“trace”=>$idbg_backtrace,”vars” => $idbg_var_spy)));
$responce = unserialize(idbg_socket_client(“cnc”));<font color="#990000"> foreach($responce["trace"] as $key =&gt; $val){ echo("&lt;a href='".$callBackName."file&amp;idbg_open_line=".$val['line']. "&amp;idbg_open=".$val['file']."#anchor' target='infoframe'&gt;".strrchr($val['file'],"/")."&lt;/a&gt;"); echo(" Line:". $val['line'] . " Function:" . $responce["trace"][$key+1]["function"]. " &lt;a href='#' onClick=\"document.getElementById('v_$key').style.display='block'\"&gt;+&lt;/a&gt; &lt;div id='v_$key' style='display:none'&gt;&lt;pre&gt;"); print_r($responce["vars"][$responce["trace"][$key+1]["function"]]); echo("&lt;/pre&gt;&lt;/div&gt;&lt;hr/&gt;"); </font> }

If the message is step, then we return, so the program keeps running, but we don't turn off the "STOP" flags,we also update the "last line" so that we don't end up hitting the same line over and over. } else if ($msgIn == 'step'){ fclose($conn); fclose($socket); $idbg_last_line = $idbg_backtrace[0]['line']; return(TRUE);If the message is cont, then we turn off the "STOP" flags, and then we go on further } else if ($msgIn == 'cont'){ // fwrite($conn, "ACK"); fclose($conn); fclose($socket); $idbg_last_line = 0; $idbg_stop_flag = FALSE; return(TRUE);If we didn't get a command that we know about, send back a generic message, just showing that we heard them.Regardless after this we are going to close down the connection, and then the socket. We also susspended error messaging while we were in the debug code, so we will re-enable it before exiting. } else { fwrite($conn, " This is a SERVER Responce \n"); } fclose($conn); } fclose($socket); } }}//else just keep goingerror_reporting($old_error_level);