Posts Tagged ‘Best Practices’

Javascript: The importance of the var keyword

I recently found a great example of the importance of the var keyword and properly scoping your variables in javascript. In the best case, we should be coding in an object oriented way and utilizing closures to properly contain our code, but sometimes we run into some plain old javascript written the old fashioned (read: messy) way.

By omitting var, we are essentially declaring the variable in the global scope, which is most likely not something we want to be doing. A great example is when declaring an iterator variable for a loop. Without var, the iterator is exposed to any functions called within the loop. If that function also has a variable of the same name that is not locally scoped, you will find that upon completion of the called function, your iterator is suddenly way off.

function parent() {
     // some (incorrect) loop calling a function
     for(iterator=0; iterator<5; iterator++) {
          child();
     }
};

// This function can then mess with our iterator!
function child() {
    iterator = 99;
}

This example shows how some code hidden away in a called function may inadvertently mess with your variables. It is only made worse when both caller and callee are disregarding scope by omitting var. The proper loop is then obvious:

for(var iterator=0; iterator<5; iterator++)

By doing so, we ensure that no one else can accidentally mess with the internals of our code. This is an easy mistake to make, but fortunately not too difficult to identify and correct.

Correct way to write a for-loop in PHP

I’ve been using PHP as one of my toolbox languages for a few years, and there are both benefits and drawbacks to it when compared to more formal OO languages like C# and Java. One of the distinct annoyances I have with PHP is the for loop, and it’s not the loop itself, it’s the arrays that the loop iterates over.

The arrays in PHP are great and highly versatile, but they also lack a length field. Many new PHP programmers simply seek out a PHP counting function (count or sizeof) and throw it into the loop.

The result is that this function is called on every iteration of the loop because the loop must re-evaluate the condition each time it runs (hopefully this is obvious). Fortunately, there is an often overlooked syntactical option to store the length in a variable for comparison that doesn’t require an extra line of code before the loop.

for($i = 0, $len = count($myArray); $i < $len; $i++) {
     // use $myArray[$i] as usual
}

And that’s it. Extremely simple, but it’s just one of those things that many people don’t even realize until they see it done.

CakePHP: Sanitizing, Validating, and Saving a list of information

Say you have a textarea field on an input form where the user inputs a list of items (like email addresses) and you intend to regularly use this list (for instance to send emails to each email address). Several things must be accomplished here:

  • Change the text into an array of items
  • Sanitize the items (unlike standard input, this list will be displayed and used much differently, so it is more convenient to store it in a ready-to-use state)
  • Validate the items (No point storing invalid email addresses)
  • Store the finished list in the database

If any step fails, the form should maintain the original input, so we also won’t touch the data on the controller side. We’ll utilize model hooks and and a custom validation method to do everything we need.

Let’s start by formatting and sanitizing the data so we can validate it. I define beforeValidate() as follows:

function beforeValidate() {
    // I allow this field to be empty
    if(empty($this->data['Survey']['recipient_list'])) {
        return true;
    }

    // try splitting by new lines first
    $list = preg_split("[\n|\r]", $this->data['Survey']['recipient_list'], -1, PREG_SPLIT_NO_EMPTY);
    $final_list = array();

    // check for comma splits
    $L = count($list);
    for($i=0; $i<$L; $i++) {
        $rows = explode(',', $list[$i]);

        if(count($rows) > 1) {
            foreach($rows as $row) {
                if(!empty($row)) {
                    $final_list[] = $row;
                }
            }
        }
        else {
            $final_list[] = $list[$i];
        }
    }

    // sanitize the final list
    App::import('Sanitize');

    foreach($final_list as &$addr) {
        $addr = Sanitize::paranoid($addr, array('@', '.', '-', '_'));
    }

    // Update our soon-to-be-validated data
    $this->data['Survey']['recipient_list'] = $final_list;

    // Save will stop if we don't return true
    return true;
}

This is obviously customized for my use, but it handles some pretty standard needs. It splits the input into items based on new lines and commas (any mix of the two). Then sanitizes each item, ensuring to preserve standard email address characters.

We then add our own validation method and define it as follows:

function validateRecipientList($check) {
    if(empty($check['recipient_list'])) {
        return true;
    }

    // Using cake's built in validation class
    $Validation = Validation::getInstance();

    foreach($check['recipient_list'] as $addr) {
        if(!$Validation->email($addr)) {
            return false;
        }
    }

    // Needed to continue
    return true;
}

I’m simply ensuring each item is an email address (note the use of Cake’s built in validation class).

Lastly, we utilize beforeSave() to serialize the list and prepare it for storage:

function beforeSave() {
    // serialize recipient list
    $this->data['Survey']['recipient_list'] = serialize($this->data['Survey']['recipient_list']);

    // Again, needed to continue
    return true;
}

All of this will now happen automagically whenever this model’s save() is called. We can even handle unserializing the list via afterFind(), but that’ll be left to the reader.

CakePHP Auth and User authorization – Which solution is right?

For the past few days, I’ve been working with the newest 1.3 release of CakePHP. It has been a while since I’ve used it, but it seems there are some great new features and some improved documentation.

I’ve been building a generic layer for a new app (and subsequent apps, hence the generic part), including user management, authentication, and user groups/roles. I’ve been trying to discern the most effective approach for implementing very customizable permissions. I am envisioning an interface similar to Drupal, where permissions are based on roles, but can be very specific. Additionally, I’d like to have support for individual user permissions when required as well.

I can see how I would accomplish this with ACL, and have also implemented a custom permissions component, but I keep wondering if there is anyway to achieve such detailed permissions without having to mix in the permissions as conditional statements and jumble up the logic.

I had more to the post, until I realized yet again that I could change directions. More to come when I refine this layer further…

Programmatically clicking an anchor tag via Javascript

Here’s a simple one that occurs often. Take for instance, the links on the sidebar of this blog. The links are wrapped in list items, however you’ll notice that you can just as easily click the big list item block as you can the link itself. Additionally, hovering over the list item triggers the hover state of the child link element. Here’s the code used to achieve this.

// Cause the parent list item to function like its child link
// Note we must use window.location as triggering a click event programmatically will not work!
$('li.widget_categories li, li.widget_archives li').click(function() {
    window.location = $(this).children('a').attr('href');
});

// When mousing over a list item, we add a class to the child link that imitates its hoverstate.
// Triggering mouse events and the like will only cause recursion errors.
$('li.widget_categories li, li.widget_archives li').mouseenter(function() {
    $(this).children('a').addClass('active');
});

// Same as above, only this time we return to normal
$('li.widget_categories li, li.widget_archives li').mouseleave(function() {
    $(this).children('a').removeClass('active');
});

Simple stuff here, but that’s about all I seem to ever have time to write down.

How many H1 tags per page? One per page

I recently searched for the answer to the question of how and why do you use H1 tags on a page. I’ve long understood that you only use one single H1 tag per page, but I was surprised that even google’s top result for the query doesn’t actually use the H1 anywhere on the page.

For simplicity sake on this blog, I use an H1 tag at the top for my name and H2 tags for posts. On single post pages and content pages, the H1 tag is used for their title and my name switches to an H2 (I rank for Austin Marron no matter what). More