swfobject.getObjectById() when flash not installed

SWFObject is the de-facto library used whenever you need to ember Flash files in your code. It takes care of smoothing all cross browser issues.

It has a getFlashPlayerVersionmethod that return a string of the current version in the form major.minor.release. Its value is 0.0.0 if Flash isn't installed.

It also provides a cross browser markup, including conditionnal comments for IE, that validate and works everywhere. The downside is that it forces you to create two elements in your markup with the same id.

Hopefully, the getObjectByIdmethod is here to return the correct DOM element based on the browser flash integration type.

But... It seems that the mechanisme is buggy when Flash isn't installed (on 2.2)

I've tested running IE9 without Flash installed and FF8 with Flash disabled, and the return of getObjectByIddiffers : I got nullin IE9 and the DOM element in FF8.

I've added a small patch to my code to take it into account :

var el = swfobject.getObjectById(id) || document.getElementById(id);

And I've also submitted a bug report.

Fix the floating issue with json_decode in PHP 5.3

When dealing with online API that are handling a lot of items (like Twitter or Facebook), you'd better be aware of a PHP limitation with json_decode.

json_decode is supposed to take a JSON string and return a PHP array or a PHP object from it.

Unfortunatly if one of the key is an int and is bigger than the max int value, it will be cast as float instead. And you'll lose precision in the process.

In my case it resulted in a complete unability to find a user in the database as the id didn't match anything. This was quite hard to find as I couldn't reproduce it on my local machine.

Know your system

My local system was a 64bits machine while the production servers were 32bits. And of course, max int precision is far bigger on 64bits machines so the error didn't pop in my tests.

If you're running PHP 5.4, the fix is easy. Just add the JSON_BIGINT_AS_STRING bitmask as 4th option like this

$decoded = json_decode($encoded, true, null, JSON_BIGINT_AS_STRING);

If you're running a 32bits machine with PHP 5.3 like me, it's a little more tricky.

The regexp

My solution is to parse the original JSON string and add quotes around ints so json_decode will keep them as string.

My first attempt was naive

preg_replace('/":([0-9]+),/', '":$1,', $encoded)

This will find any int between ": (marking the end of a key) and , (marking the start of the next key), and replace it with the same string but enclosed in quotes.

I soon found out that this did not cover all the cases, especially if the int key was the last of the JSON, it won't be followed by a , but by a } instead.

So, I adapted it a little bit :

preg_replace('/":([0-9]+)(,|})/', '":"$1"$2', $encoded)

Ok, it worked better. Any int key in the JSON, anywhere will be enclosed in quotes.

It was a little overkill so I decided to limit it to keys of at least 10 digits

preg_replace('/":([0-9]{10,})(,|})/', '":"$1"$2', $encoded)

Better. But still not perfect.

As I soon discovered, sometimes Facebook returned JSON containing JSON itself (in Request dataor Credit order_info for example).

The previous approach would add quotes around ints in JSON escaped string and would thus corrupt the whole key.

This time, I added a final touch. I only added quotes around int that were not in an escaped JSON string themselves, by checking that the closing quote of the key wasn't escaped.

preg_replace('/([^\\\])":([0-9]{10,})(,|})/', '$1":"$2"$3', $encoded)

Here it is, the final fix. I might have forgotten some corner cases, but at least it works for my current application.

Hope it helps !

Accessing a frame with Firebug console

If you want to access the Javascript console of an inner frame of a webpage, know that you can "browse" through the window as you could browse through a file system.

For example, if you want Firebug to use the first frameof the page as its current window object, just type the following code in Firebug console :

cd(window.frames[0])

This proved immensely useful when debugging a Facebook application.

Toggling insert/normal mode in vim with CapsLock

You know that CapsLock key on your keyboard ? The sole usage of this key is to SHOUT ON TEH INTERNETS§§§. I decided to disable it completly as I never use it on purpose.

I also wanted to use it in vim to toggle between normal and insert mode with one key instead of the default i/Esc.

Disabling CapsLock

Disabling CapsLock is a fairly straightforward process. The xmodmap program is responsible for binding keyboard events to your software and you can change the default behavior by creating an ~/.Xmodmap file.

Just put the following code in it and the pressing the CapsLock key will no longer block your next keys in Caps.

clear Lock

Catching it in vim

Now, to get it in vim, you'll have a little more work to do. First, CapsLock is not one of the default vim keycodes, so you won't be able to remap it to any useful function. To use it in vim, we will hook it directly on xmodmap to another key, one that is part of vim default keycodes.

I choose the virtual F13 key. Your physical keyboard might only have F keys from 1 to 12, but the internal software seems to be able to react to 37 of them. So, why not using them ?

In your ~/.Xmodmap file, this is as easy as adding the following line

keycode 66 = F13

66 is the internal code for the CapsLock key. We just define that pressing the physical CapsLock key should trigger the F13 virtual key.

Now, in ~/.vimrc, we will tell vim to explictly listen to extended F keys (from 13 to 37) which it does not do by default.

set <F13>=^[[25~

^[[25~ is the special keyboard code sent to vim when the F13 key is triggered. Here we just define that such a keyboard code should be interpreted in vim as an <F13> vim key.

Now, you can use <F13> in your custom vim mappings

Toggling normal/insert mode in vim

vim accepts two kinds of mapping. Those triggered in normal mode (using nnoremap) and those triggered in insert mode (using inoremap).

Here we want that pressing CapsLock (or <F13> in vim as we defined) in normal mode will go to insert mode, like pressing i does. And we also want to get back to normal mode when pressing CapsLock in insert mode, just like pressing Esc does.

nnoremap <F13> i
inoremap <F13> <Esc>l

Notice the l after Esc. It is here to prevent the caret to move back one character when exiting insert mode.

Fixing the shell

One last thing to fix is your shell. By defining in xmodmap that pressing CapsLock would trigger an F13 event, it means that whatever software that react on F13 will now react on CapsLock. Unfortunatly, zsh does react on F13. It insert a ~ character on it (just like it does with F12).

To disable it, we'll simply define a key binding in ~/.zshrc so pressing F13 does nothing.

bindkey -s "\e[25~" ""

Here it is. You can now press CapsLock anywhere and it won't have any effect. Plus, pressing it in vim will toggle insert/normal mode.

Getting the list of Facebook pending requests of a user

Getting the list of pending facebook requests of a user a few weeks back was as easy as calling https://graph.facebook.com/me/apprequests?access_token={user_access_token}

We discovered around the 1st October that some of our requests were failing in production, without any more clue than some "OAuthException : access_token invalid" messages in our logs.

It appears that FB changed the way their endpoint react to /apprequests call. Of course, they didn't bother telling us.

The previous url does not work anymore. Switching the user accesstoken to the app accesstoken as documented does not work (as usual with FB documentation). It returns an error.

Instead, the following call wil yield the correct result : https://graph.facebook.com/{user_id}/apprequests?access_token={app_access_token}