WordPress and the Dreaded “You do not have sufficient permissions to access this page.” Error

After cleaning a customer’s two WP instances after a PHP redirect hack, they asked me to obfuscate and harden their backup to decrease the likelihood that a second attempt would not be successful.

One task was to change the wordpress table prefix so that standard-named/dumb SQL injection attempts would not be successful. It was simple enough to get the parallel instance up and running, but after migrating their previous (and cleaned) table data, no one could login. No matter the access level, the login landing page would result in the dreaded error:

You do not have sufficient permissions to access this page.

Rather than start from zero, reinstall and configure all their plugins, reinstall and reconfigure their heavily customized theme, and most importantly, lose all of their users and post/page data, I needed to dig in and backtrack the issue.

The standard wordpress table namespace is “wp_“.

I picked some random names from popular culture to isolate their instance namespaces.

In order to migrate from one table namespace (standard OOTB “wp_“) to another (say, “foo_“), several foo_usermeta and foo_option values need to be updated to correctly reflect the target namespace.

The * in the following represents the new table namespace selected during setup.  The OOTB value will be wp_[value], which would need to be changed to foo_[value].

The following *_usermeta meta_key values need to be updated:

  • *_capabilities
  • *_user_level
  • *_dashboard_quick_press_last_post_id
  • *_capabilities

Keep in mind that *every* user will have these four meta_keys.  If you have hundreds of users, it would behoove you to write a quick SQL or PHP loop to iterate and update the values.

In addition, one must also change an option_name in the *_options table:

  • *_user_roles


I hope this saves someone out here some time, frustration and headache.

Advertisements

IE7 z-index Bug and Workaround

For the tl;dr Crowd

find all the parent elements in your page that are

  • position : relative
  • position : absolute
  • position : fixed

Set descending z-index values for each. I.e., the first element that matches the above should start with say z-index 1000, the second should get 999, and so on until all positioned elements are given descending order z-index values.

This fix will only work top-left to bottom-right.  Meaning, if you have normal fly-out menus, the above should get your visually at par with Chrome or Firefox.  This may not work for you if your the absolutely positioned visual element is lower down in the DOM hierarchy.

The (really) Long Version

IE7 is an order of magnitude easier to build web applications and web pages versus the Sisyphean effort required to get IE6 compliant.  But it is not without it’s own set of unique and equally difficult bugs.

One bug that has several posts scattered around the ‘net is the infamous IE7 z-index stacking order bug.  A one-sentence precis of this bug is z-indexed elements do not respect their assigned stacking order when used in conjunction with absolute and relative positioning.

Some required reading:

  • Quirksmode – from 2006, and maybe a bit dated
  • Brenelz – decent fix, but incorrect assessments in main post
  • StackOverflow – accepted solution has the correct analysis, and a fix for the asker
  • Webdemar – offers a simple solution – it may be all you need to fix your issue

A brief sample

To illustrate, examine this example: Simple Example

View the source of the sample page to get an idea of the markup that will cause this bug.  The example shows exactly what is needed to fix this particular instance, but to fix the doubtlessly more complicated examples found in most web applications/pages requires a bit more digging, and a lot more understanding.

If the above links didn’t solve your issue, you are in the boat I was (still am?) in; sometimes floundering to apply what should be turn-key solutions/workarounds into magical fixes.

The problem

The gist of the IE7 z-index bug is that a positioned element (i.e., one that is positioned absolutely, relatively, or fixedly) will reset the z-index stacking order to 0.  In a vacuum, this would go unnoticed, but when applied in conjunction with other elements that are absolutely positioned, the bug symtoms show themselves.

The solution at a glance

The workaround is to cascade a reverse z-index through your DOM; in effect, you assign the highest z-index to the positioned elements as you work your way down through the node tree.  Assume the following example has position:relative for all the elements:


body
    div - 10000
        div - 9900
            div - 9890
            div - 9880
                div - absolutely positioned menu (or something)
                    - this will display above 9800 (and its widget), 9700, etc.
        div - 9800
            div - widget, child nodes are absolutely positioned
                (before the z-index fix, this would obstruct the menu)
        div - 9700
    div - 9000
    div - 8000

A simple bit of Javascript could massage the DOM for you automatically.  Say the problematic widget is an absolutely positioned flyout menu that is built and applied as the child of DIV 9890.  Upon instantiation, have a utility method crawl up the DOM tree and sniff for postioning, and if found, apply a descending z-index value.  Something like the following pseudo-code should get you well on your way:

var IE7Kludge = {
    zIndex : 10000,
    applyIe7Workaround : function(el) {
        var p = el.parentNode;
        while(p != document.body) {
            if(p.style.position == 'absolute' || p.style.position == 'fixed' || p.style.position == 'relative') {
                p.style.zIndex = this.zIndex--;
            }
        }
    }
}
IE7Kludge.applyIeWorkaround(document.getElementById("myWidgetRootId");

 

Another problem

The crux of the issue is finding all those elements in your DOM hierarchy that do have positioning.  In the apps I work on, there are literally dozens of widgets running side-by-side that instantiate, append, and apply behavior after the DOM has loaded fully.  The above solution caught roughly 75% of the issues, but there were lots of stragglers that I had to manually find and apply my fixes.  For this, I used a slightly modified version of the above, and ran it before my widget-triggered version (pardon the jQuery, but one could easily modify this to fit POJS or any number of other libraries that offer CSS selectors):

var IE7Kludge = {
    zIndex : 10000,
    fixStragglers : function(j) {
        var idx = this.zIndex;
        j.each(function(i, el) {
            idx = idx-10;
            $(el).css("zIndex", idx);
        });
        this.zIndex = idx;
    }
}
IE7Kludge.fixStragglers($('.myCrazy, .selector, .that-finds-all-relative-positioned-elements'));

Yet another problem

With the above two utility methods, I was able to get to about 90% compliance.

The last 10% is due to the fact that this workaround works only top-left to bottom-right. If I only supported widgets that flew out to the left, or top to bottom, there would be no more work to be done, but if you have widgets that fly out bottom-up (say, a viewport aware info bubble that pops above an anchor element if near the bottom of the viewport), its hierarchical z-index stacking is below elements above it in the DOM.  So yet another set of headaches to deal with.

The fix for this last issue is similar to the first kludge, walking the DOM.  There are some caveats, and this may or may not apply to your situation:

  1. While running the 1st fix, I made sure to keep references to the modified elements in order of manipulation, working my way up the DOM tree.  It was easy enough to do this by .push()’ing the element references into a handy array that I could access in a callback when the fly-out closed itself.
  2. While iterating through that array, we must treat it FILO (first in, last out) stack, as IE7 apparently calculates the z-index stacking order from the root node onwards, not as a gestalt sum after all behaviors are applied.  The handy array.pop() method makes this a simple exercise.

The pseudo code for this (again in jQuery-speak):


var IE7Kludge = {
    zIndex3 : 10000,
    seed : new Date().getTime(),

    generateGUID : function() {
        return "custom_id_" + this.seed++;
    }

    handleInstanceManipulation : function(el) {
        var pos, j, z, p = el.parentNode;
        var backup = [];
        var z3 = this.zIndex3;

        while(p != document.body) {
            j = $(p);
            pos = j.css("position");
            z = j.css("zIndex");

            if(pos == 'relative' || pos == 'absolute' || pos == 'fixed') {
                if(p.id == "") {
                    p.id = this.generateGUID();
                }

                backup.push({
                    selector : p.id,
                    zIndex : z
                });
                j.css("zIndex", z3--);
            }

            j = null;
            p = p.parentNode;
        }

        return backup;
    },

    resetInstanceManipulation : function(backup) {
        var i;
    	while(backup.length > 0) {
    	    i = backup.pop();
    	    $(i.selector).css("zIndex", i.zIndex);
    	}
    }
}

Home stretch

With the combination of the above 3 workarounds, I was able to get my web app fully compliant in IE7. For convenience’s sake, here’s a skeleton of my static methods. If you’re in a jQuery shop, it’s basically a drop-in, otherwise you’ll have to account for how the DOM reports CSS values (instance, javascript assignment, and external css files). Hope this helps someone.

var IE7Kludge = {
    zIndex3 : 10000,
    zIndex : 10000,
    seed : new Date().getTime(),

    generateGUID : function() {
        return "custom_id_" + this.seed++;
    },

    applyIe7Workaround : function(el) {
        var p = el.parentNode;
        while(p != document.body) {
            if(p.style.position == 'absolute' || p.style.position == 'fixed' || p.style.position == 'relative') {
                p.style.zIndex = this.zIndex--;
            }
        }
    },

    fixStragglers : function(j) {
        var idx = this.zIndex; // this value must stay at the preset value every time, so we copy it
        j.each(function(i, el) {
            idx = idx-10;
            $(el).css("zIndex", idx);
        });
        this.zIndex = idx;
    },

    handleInstanceManipulation : function(el) {
        var pos, j, z, p = el.parentNode;
        var backup = [];
        var z3 = this.zIndex3; // this value must stay at the preset value every time, so we copy it

        while(p != document.body) {
            j = $(p);
            pos = j.css("position");
            z = j.css("zIndex");

            if(pos == 'relative' || pos == 'absolute' || pos == 'fixed') {
                if(p.id == "") {
                    p.id = this.generateGUID();
                }

                backup.push({
                    selector : p.id,
                    zIndex : z
                });
                j.css("zIndex", z3--);
            }

            j = null;
            p = p.parentNode;
        }

        return backup;
    },

    resetInstanceManipulation : function(backup) {
        var i;
    	while(backup.length > 0) {
    	    i = backup.pop();
    	    $(i.selector).css("zIndex", i.zIndex);
    	}
    }
}

 

Sending a FAX with Google Voice

To send a FAX with Google Voice, do the following:
1. set a PIN for your Voice account
2. send FAX to this number:
[GVoice #] Pause * Pause [PIN] Pause 2 Pause [Dest FAX#] #
“Pause” is the pause button to the right of the keypad.

Remove Files from ClearCase

Because CC sucks, here’s the quick way to remove files, elements, folders, etc.:

cleartool rmname /vob/test/a/b.txt

BSD Routing for SSH/SCP Hackery

Problem: My dev laptop at work has two network connections, one internal and proxied/firewalled to hell and back and the other is sitting on a public facing router with no proxies or firewall in the way.  The internal-only connection we’ll call en0 and the external-facing one, we’ll call en1.

The issue is that en0‘s routing disallows all outbound connections to anything that isn’t port 80/443 (HTTP/HTTPS). en1‘s connectivity is slow, so we want to keep as much traffic to en0 as possible, especially since fun things like disk shares, my Synergy2 host and internal-only sites are only available via en0.

However, I do need to connect to my co-lo offsite via SSH/SCP to do some work.  I can force all traffic temporarily to en1 by disconnecting or disabling en0 for the duration, but that means I’m forced to use the laptop’s keyboard/trackpad and sit awkwardly until my business is done.  F-that.

Solution: Use BSD’s routing (route) utility to direct TCP traffic to certain destinations through a manually set (static) gateway.

Situation:

en0‘s gateway is 10.33.x.1

en1‘s gateway is 172.16.x.1

en0 is higher in the priority list (duh, else this wouldn’t be a problem)

the co-lo’s IP address is AAA.BBB.CCC.DDD

Add a routing rule for AAA.BBB.CCC.DDD to use en1‘s gateway when the destination matches:

route -n add AAA.BBB.CCC.DDD 172.16.x.1

Voila.

Yes, this will only work at my particular location with my particular situation for exactly 1 address.  One can adapt the rules a bit and use bitmasks to drive more traffic to the other gateway, but this works for me.  If I can figure a way to use a different gateway based on destination port/protocol, I’ll update this post.

Javascript toSource() in IE6/7

Mozilla based browsers have a pretty nifty instance method “toSource()”. It simply outputs a string literal representation of any Javascript object, which is at heart, *anything* in the Javascript interpreter.

The main reason I use this method is to do a quick & dirty deep copy of Javascript objects and arrays. When paired with the “eval()” function, you can be 100% sure that the new array or object you just created is its own instance and doesn’t have reference pointers to existent objects or arrays.

My main use-case is using an object as hashmap or associative array, but needing to copy it regardless of whether one of its member attributes is another object or array (which would preserve the pointer). Performing a toSource() and eval() allow you to do just this.

var burdensomeBabyNames = [ ... ]; // imagine a deep array of strings, other arrays, objects, etc.
// now we have a deep copy, quick and easy|dirty
var burdensomeBabyNamesCopy = eval(burdensomeBabyNames.toSource());

For example, say you have an array of names in memory: “Oedipus”, “Ophelia”, “Freya”, “Loki”, “Lachesis”, “Atropos”, and “Morta”.

If that array was instantiated in memory as “burdensomeBabyNames”, the string literal representation would look something like:

var burdensomeBabyNames = [
  'Oedipus', 'Ophelia', 'Freya', 'Loki',
  'Lachesis', 'Atropos', 'Morta'
];

In a Mozilla based browser, one could call “toSource()” return an useful textual representation of the string literal. I.e., calling:

var xNames = burdensomeBabyNames.toSource();

The var xNames would now contain the string:

['Oedipus','Ophelia','Freya','Loki','Lachesis','Atropos','Morta']

Great, huh? That’s really useful if you never have to consider the Internet Explorer crowd, but since IE still owns a ridiculously high percentage of the browser usage pie, folks who use this functionality need a work-around.

Anyone who’s worked with asynchronous calls vis-a-vis JSON (Javascript Object Notation, see http://www.json.org) will see that the toSource() call is just a rough draft of the much deeper JSON.encode().

The same example as above could be rewritten to use JSON encode and decode:

var burdensomeBabyNames = [ ... ]; // imagine a deep array of strings, other arrays, objects, etc.

// serialize or "toSource()" the array
var burdensomeBabyNamesJSON = JSON.encode(burdensomeBabyNames);

// now we have a deep copy, quick and easy|dirty
var burdensomeBabyNamesCopy = JSON.decode(burdensomeBabyNamesJSON);

One could just include the minified version of JSON.js from the above link and call it good. If you happen to be working within a framework like YUI (Yahoo UI, see http://developer.yahoo.com/yui) or ExtJs (see http://www.extjs.com), the encode/decode functionality is already folded into the core library.

IE6 Javascript Form Submission – Hit or Miss

Internet Explorer 6, a venerable old browser to be sure, is still widely used despite the availability of much better (and free) alternatives. This continues to be a time-sink for any front-end developer.

While not at all a technical observation, my one reproducable use-case around this bug was by:

  1. Programatically creating a DOM Element <div>
  2. Dynamically creating and assigning an onclick event handler to the <div>
  3. Trying to submit a given form with validation and some custom hidden <input> fields.

What I observed is that the click propagation doesn’t seem to want to return from the onclick handler function

Here’s a fun one:

document.getElementById("myFormId").submit();

Should be straightforward, correct? In some select cases, this actually will not work.

The workaround:
Set the scope to the document level and force submission with a short timeout.

document.doSubmit = function() {
    document.getElementById("myFormId").submit();
}
setTimeout("document.doSubmit();", 50);

Putting it all together:
Here’s your trigger, say an <img> tag:
<img src="..." onclick="submitMyForm();" />

Here’s the form submit function:

function submitMyForm() {
    // do some validation, completion checking, etc.
    ...
    // now call the externalized submit function
    document.doSubmit();
}

Here’s the setTimeout handler:

document.doSubmit = function() {
    document.getElementById("myFormId").submit();
}

The <img> tag’s onclick event calls submitMyForm() which then calls document.doSubmit() .