853PHP define(): single or double quotes?

I recently came across the following situation. A new server, a client-defined database, a database name like this: 'my-database'. Checking if the DB exists in PhpMyAdmin, everything checks out.

Putting all the details in wp-config.php should also work, right?

define('DB_NAME', 'my-database');

Hmmm. No, not quite. Error establishing a database connection

Could it really be, that the dash in 'my-database' messes up the DB_NAME? Apparently yes.

define('DB_NAME', "my-database");

Ok, problem solved. As for why, that's still an open question.

851Resizing Image in the OSX Terminal with sips

Resizing and reformatting images should a straight-forward exercise, after a few false starts with Photoshop and ImageMaverick, I found a nice and simple solution.

There are several options, Photoshop's 'Automate' feature or ImageMaverick, but more often than not they are overkill. (Or as in the case of Photoshop, you run into some unspecified errors, which leave you with thousands of open windows... Neither elegant nor effective).

I wish there were a simple command-line utility that would allow for the painless resizing and reformatting of images. Luckily there is, it's called sips - scriptable image processing system.

sips -s format jpeg -s formatOptions 80 -Z 480 *.png --out jpeg

The "-s" modifier means "set", -s format jpeg means set the output format to jpeg, -s formatOptions 80 means set the jpeg quality to 80.

-Z 480 specifies that the largest side of the image should be 480px.

*.png are the input files.

--out jpeg is the output directory. Call it anything you like, but make sure it exists.

849Resetting brew

From http://codesandnotes.com/how-to-reset-homebrew/

Recently I had some trouble updating my Homebrew install and while I do like digging into the perfect solution sometimes an easy fix is all you need. These commands will overwrite your local brew with the latest from Git and do a hard reset on your local install, essentially clearing everything. Copy and run these lines in your shell one after another. If it says ‘remote origin already exists’, just continue.
# change to your brew directory
cd `brew --prefix`

# same as
cd /usr/local

# hard reset git
git remote add origin https://github.com/mxcl/homebrew.git
git fetch origin
git reset --hard origin/master

841Timing with console.time()

Everyone working with on more complex JS application sooner or later has the need to time operations.

This code is purely for historic purposes and standing reminder to check out the Chrome DevTools Documentation before writing your own utility functions.

// Timer Function
(function() {
    self.timer = timer;
    timer.version = "1.0.0";
    timer.names = {};

    function timer(name) {
        return {
            start: function() {
                timer.names[name] = {};
                timer.names[name].start = new Date().getTime();
                console.log("Timer '" + name + "' started.");
            },
            stop: function() {
                if (timer.names[name] && timer.names[name].start) {
                    var diff = new Date().getTime() - timer.names[name].start;
                    console.log("Timer '" + name + "' took " + diff/1000 + " sec.");
                    delete timer.names[name];       // remove timer object
                }   

            },
            test: function() {
                console.log(timer.names);
            }
        }
    }

})();

// Usage

timer("test").start();
timer("test").stop();   // logs elapses time..

The perfect built-in solution is console.time() and console.timeEnd():

console.time("test");
console.timeEnd("test");    // logs elapses time..

Still, I have to say, I was quite pleased how my own function turned out..

840Converting a string into a number in Javascript

var intStr = "101011";
var floatStr = "1.234";

The obvious solution is to parse the string into an integer, in most cases with base 10:

var int = parseInt(intStr, 10);    // 101011
var float = parseInt(floatStr);    // 1.234

A shortcut to coerce an integer string into a number is the addition of a '+' sign before the integer string:

+intStr;    // 101011
+floatStr;    // 1.234

Care should be taken when removing the space between the equal and the plus sign. =+ converts to a number, += adds the stings together.

intStr = +intStr;    // 101011

intStr =+ intStr;    // 101011
intStr += intStr;    // "101011101011"  !!!!

We leave operations with the minus sign and multiple plus signs for another time.

839Empty an Array, but Preserve it’s Association

Creating an array 'a', creating an association from 'b' to 'a'.

var a = [1,2,3,4];
var b = a;

console.log(a);   // [1,2,3,4]
console.log(b);   // [1,2,3,4]

But what happens, when I want to empty the array using the 'b' variable? The first obvious attempt would be to assign a new, empty array to 'b'.

b = [];

console.log(a);   // [1,2,3,4]
console.log(b);   // []         NG!

Hmmm. Something's not quite right here. By assigning a new, empty array to 'b' we also lost our association with the 'a' array.

How can we keep the association and empty the array? T

b.length = 0 ;

b.push(1);
b.push(2);
b.push(3);
b.push(4);

console.log(a);   // [1,2,3,4]
console.log(b);   // [1,2,3,4]    OK!

There is also a slightly different way using splice.

b.splice(0, b.length);

b.push(1);
b.push(2);
b.push(3);
b.push(4);

console.log(a);   // [1,2,3,4]
console.log(b);   // [1,2,3,4]    OK!

In case you wonder, where this can be useful. Let's assume you have a global object and somewhere in it there's an array you want to do something with.


var myGlobalObj = {};
myGlobalObj.reallyLong = {};
myGlobalObj.reallyLong.andAnnoying = [];

var testFunction = function() {
    var sweet = myGlobalObj.reallyLong.andAnnoying;     // associate
    sweet.length = 0;   // empty sweet & myGlobalObj.reallyLong.anAnnoying Array
}

832WordPress, wp_enqueue_script & Order-of-Loading

The Wordpress way of loading Javascript files is through wp_enqueue_script. This ensures that no scripts are loaded twice, and it allows for a mechanism to specify dependencies.

I had the following situation:

A plug-in was loading a JS file with wp_enqueue_script, something like this:

function addMyPluginScript() {
    wp_register_script('my-js', plugins_url('/my.js', __FILE__, array('jquery'), '1.0', false) );
    wp_enqueue_script('my-js');            
}    

add_action('wp_enqueue_scripts', 'addMyPluginScript');

In my theme's functions.php I had the following:

function load_scripts() {                           
    wp_enqueue_script('jquery');
    // ... other scripts
}    
add_action('wp_enqueue_scripts', 'load_scripts');

But although I specified the dependency of 'jquery' in the plug-in's code, the plug-in's JS got loaded BEFORE the theme's jQuery. Hmmm...

The solution was a closer look at the add_action function. Usually it is called with 2 parameters, the hook name and the callback function. But there's also a third, optional parameter: priority. It defaults to 10, and Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action.

The fix for out problem: Load the functions scripts before anything else:

function load_scripts() {                           
    wp_enqueue_script('jquery');
    // ... other scripts
}    
add_action('wp_enqueue_scripts', 'load_scripts', 1);    // 1 is smaller than the default 10...

829Digging a tunnel to a remote SFTP Server, Part 2

Back in Part 1, I was using a tunnel and a SOCKS proxy to connect to a remote server. While this might work in certain conditions, other circumstances might call for other solutions.

Take this case.

Recently our Sysadmins changed to login procedure to our servers. Instead of just logging on like this...

localmachine:~ me$ ssh username@host

...we are now forced to jump through another hoop:

localmachine:~ me$ ssh username@host
username@host's password: •••••••
Last login: Tue Aug 14 10:39:17 2012
[username@host]$

[username@host]$ ssh username@anotherHost

I have to guess, that for reason's of security, it's not possible to log-in directly to anotherHost from my local machine: Any connection has to go through the host machine.

While some like to edit their text files with the very powerful, but slight archaic vi or Emacs, some others prefer more a more civilised approach and use tools like TextMate.

But if the text files are on a remote server, which needs to be logged-in from another server, how can I use TextMate to edit files there?

Enter the Tunnel

Cyberduck, the ever-popular SFTP application, can lend us a hand in editing the text files. A simple cmd-J, and the text file on the server opens in TextMate, cmd-S saves the modified file back to the server.

But how exactly do we open the tunnel? How do we start the port-forwarding?

ssh usename@host -L 1024:anotherHost:22

Let's dissect this command:

ssh usename@host open a connection to the host with our username. Of course you'll be prompted for your password.

-L 1024:anotherHost:22 is where the magic happens. It specifies the local port on your machine (in this case: 1024) to which the remote port (22) of anotherHost is mapped. And all this happens by way of the host machine.

Other switches which could be helpful for this command are: -f send ssh to the background -N stops the execution for remote command.

Check the ssh man pages for more details.

If you prefer a GUI for opening the tunnel, have a look at Fugu.

It does basically the same, only with a graphical user interface. If that removes or adds confusion is for you to decide.

If we look at the ssh command that Fugu is generated, we see that we were basically doing the same before:

/usr/bin/ssh -N -L1024:anotherHost:22 username@host -oPort=22 -v

825Prototypal Inheritance and it’s Problem with Objects

Prototypal inheritance in Javascript is one of these features that sets it apart from other languages. A quick reminder:

var myDog = {};
myDog.legs = 4;
myDog.type = "Dachshund";
myDog.color = "brown";
myDog.says = "wau wau wau";

var yourDog = Object.create(myDog);
yourDog.says = "wan wan wan";

console.log(yourDog.type, yourDog.says);
> "Dachshund", "wau wau wau";

console.log(myDog.type, myDog.says);
> "Dachshund", "wan wan wan";

myDog is the prototype for yourDog, together they for a prototype chain. Any properties that would be added in myDog would also be accessible in yourDog. If yourDog adds a property with the same name (yourDog.says), this new property is returned when called. If a property is not defined, but present in the prototype, it will shine through.

So far so good.

Let's say we have an Array of dogs and we would like to prototypal inherit that whole array.

var myDogs = []
// fill array with dog objects

Following the pattern from above, the way to make a yourDogs array should be like that:

var yourDogs = Object.create(myDogs);

Let's update the first dog of the new yourDogs array to say something else:

yourDogs[0].says = "wow wow wow";

One would expect, that - because of the prototypal inheritance - that the changed value would only hide the original value. Let's check:

console.log(myDogs[0].says);
> "wow wow wow";

Ouch. The value was not as expected added to the prototypal branch only, but also to the original object. The prototype object and its chained offspring have the same object. Why is that? The answer is, that only variable types of Number, String, Boolean, etc are passed by value. Objects - and Arrays are objects - are passed by reference. (Check with typeof() to confirm the type of a variable.). That means the objects in our arrays are one and the same, and therefore any change in would will also occur in the other.

Seems logical, but still expectations are betrayed.

Let's consider the following case, this time without dogs. You have an array with objects and you want to apply a filter to some properties of the objects, which should be collected in another array. But - and this is crucial - you don't want the original array objects to change.

var original = [];
// add many, many objects

Because we saw before, that any changes in a new object would also reflect in the old one, we might be tempted to make a deep copy of the new one and then make our changes.

var copy = [];
$.extend(true, copy, original);     // Yes, that's jQuery
copy.map(function(element) {
    // make our changes to element
    //return element;
}

It's works, but it's rather kludgy. It takes quite a long time to make the deep copy and the prototypal chain breaks by doing that. Note also that the return of the map() function is not assigned to a new variable, and that the function does not need to return anything actually - because we are operating on the object directly.

A better solution would be this:

var better = copy.map(function(element) {
    var protoype = Object.create(element);  // create prototypal inheritance
    // make our changes to element
    return protoype;
}

better is now an array of objects which are prototypal linked to the original array. Any newly added properties will only be added to the new array - covering any properties which are already present in the original one.

console.log(original[0].dog.says);
> "wau wau wau"
console.log(better[0].dog.says);
> "wau wau wau"

better[0].dog.says = "wuff wuff wuff";

console.log(original[0].dog.says);
> "wau wau wau"
console.log(better[0].dog.says);
> "wuff wuff wuff"

That would I would have expected in the beginning. The nice things about Javascript is, that even when in works in unexpected ways, it's usually fairly trivial to align it again with your imagination. And sorry for bringing the dogs back.

819Single, Multiple Files and Javascript’s FileReader API

Getting a single file (with convenience jQuery event handler)

     
$('#open #chooseFile').change(function(e){
    var fileList = e.target.files;
    // get the one and only file
    var file = fileList[0];
    // further process file content...
    var reader = new FileReader();
    reader.readAsText(file, "text/plain");      
    reader.onload = localLoaded;
    reader.onerror = localError;
    // ...
});

Getting multiple files:

           

$('#open #chooseFile').change(function(e){
    var fileList = e.target.files;
    // loop over the files

    for (var i=0, file; file=fileList[i]; i++) {
        var reader = new FileReader();
        reader.readAsText(file, "text/plain");      
        reader.onload = localLoaded;
        reader.onerror = localError;
        // ...
    }
});