Testing localhost instances on devices using a proxy

I wanted to be able to access my localhost from my iPhone. This article on Egalo told me how to do it.

Essentially, you run a Proxy Server from your laptop and point your device at the proxy in the wifi settings. The article suggests using SquidMan as a proxy, largely because it is fairly easy to set up and it’s free.

As Egalo explains, there’s two lines in the Squid template (conf file) that need some loving:

Comment out the http_access deny to_localhost line like so:

# protect web apps running on the proxy host from external users
# http_access deny to_localhost

And add the following line (and comment) in the file somewhere – I threw it at the bottom:

# hosts file
hosts_file /etc/hosts

On the “Clients” tab of SquidMan preferences

Add an entry for your IP range. I enter the following on mine: 10.0.0.0/16

Once you’ve tweaked the template; added your allowed clients (see the article); started the proxy server; and pointed your device at the proxy server, you should be good to go!

Advanced GitHub issue filtering

A little over a year ago, I posted about using dotjs to add buttons for advanced issue filtering on GitHub. With GitHub’s launch of their revamped Issues page, or dotjs code is no longer needed! Issue filtering is where it’s at:

Filters

Example filter on Twitter Bootstrap’s GitHub page

Example: all bugs that aren’t labeled as “help wanted”

If you are looking at Twitter Bootstrap CSS issues, but don’t want to see items that are awaiting QA, add -label:"help wanted" to the Filter box. It should look like this:

is:open is:issue label:css -label:"help wanted"

Example: involving mdo with more than 2 comments

To get all open CSS issues on Twitter Bootstrap that have involved mdo in some way and have >2 comments:

is:open is:issue label:css involves:mdo comments:>2

Useful links

That’s just the tip of the iceberg for what can be done with the new Filter UI. GitHub has some docs that are worth a read:

Discovering the events attached to elements in jQuery

If you have a need to find what events are attached to an element in jQuery, here’s what you do:

Finding events attached to the document:


jQuery._data( jQuery( document )[0], 'events' );

Finding events attached to an element with an ID of bacon:


jQuery._data( jQuery( '#bacon' )[0], 'events' );

Here’s a snippet I’ve been using in the console:

var events = jQuery._data( jQuery( document )[0], 'events' );
for ( var i in events.click ) {
  console.log( 'click ' + i + ' :: ' + events.click[ i ].selector );
}

Bringing back the console API on Netflix and Facebook

Facebook and Netflix have implemented some code that breaks the console API in Chrome by changing the getter/setter for the console property on the window object. The purpose is noble – to help avoid a social engineering attack – but as a developer it irks me. I want my console when and where I want it.  In short order, Zach and I had a fix in place that unbreaks the console.

Using dotjs – which I’ve written about at Gigaom Kitchen – we can run the following code before the console-breaking code executes (here’s my dotjs file):

var s = document.createElement('script');
s.innerHTML = 'Object.defineProperty(window, "console", {writable: false});';
document.head.appendChild( s );

MDN writes on the writable property:

When the writable property attribute is set to false, the property is said to be “non-writable”. It cannot be reassigned.

Now I get my console :)

Setting /etc/hosts on an Android Emulator using a Mac

Testing sites on mobile devices is a necessity. When you find a bug that needs some loving and you want to do the code tweaks on your localhost, the Android emulator balks. It doesn’t know anything about your localhost. Luckily, you can resolve this by editing the emulator’s /system/etc/hosts/ file. Here’s what to do:

First, start your emulator setting a partition size so the emulator doesn’t throw an out of memory error:

$ emulator -avd nameOfAvd -partition-size 512

Next – in another shell window/tab – check what devices are running (so you can edit the one you want):

$ adb devices

List of devices attached
emulator-5554 device

The emulator-5554 is the device I started with the emulator command. Right now it is in read-only mode. Remount the device to make it writable

$ adb -s emulator-5554 remount

remount succeeded

Now that it is remounted, grab the hosts file and put it somewhere on your filesystem (I use the Desktop):

$ adb -s emulator-5554 pull /system/etc/hosts ~/Desktop/

6 KB/s (25 bytes in 0.003s)

Edit the ~/Desktop/hosts file as needed with the editor of your choice:

127.0.0.1        localhost
192.168.1.100    bacon.local

Finally, push that hosts file onto your emulator:

$ adb -s emulator-5554 push ~/Desktop/hosts /system/etc/hosts

45 KB/s (249 bytes in 0.005s)

BAM! The emulator can now access sites using the hosts specified in the newly edited hosts file.

Useful docs: emulator and managing AVDs

Activating BuddyPress for PHPUnit WordPress-tests

I have found myself writing PHPUnit tests for WordPress plugins lately (using wordpress-tests) and the code that I’m working with has a dependency on BuddyPress.  Enabling BuddyPress for WordPress unit testing requires a bit of hoop jumping because you can’t use the wp_tests_options global variable as you would any other plugin in your local bootstrap file (which is configured in phpunit.xml):

$GLOBALS['wp_tests_options'] = array(
  'active_plugins' => array(
    'wp-debug-robot/wp-debug-robot.php'
  ),
);

Instead, run the following within your bootstrap file after you’ve included the wordpress-tests bootstrap:

  // activate the buddypress plugin for your network (if you aren't running MULTISITE, the third parameter should be FALSE)
  activate_plugin( WP_CONTENT_DIR . '/plugins/buddypress/bp-loader.php', '', TRUE, TRUE );

  // set the components that you want to activate
  $active_components = array(
    'activity' => TRUE,
    'friends' => FALSE,
    'groups' => FALSE,
    'messages' => TRUE,
    'xprofile' => TRUE,
    'blogs' => TRUE,
  );

  // update your site's bp-active-components option with your configured settings
  update_option( 'bp-active-components', $active_components );

  // include the file that contains the logic you need to create BuddyPress tables
  require_once WP_CONTENT_DIR . '/plugins/buddypress/bp-core/admin/bp-core-schema.php';

  // run the installer
  bp_core_install();

With that in place, your tests should have BuddyPress classes & functions available to you – complete with BP tables in your database!

Bypassing Output Buffering in PHP

I’ve been developing with PHP for over a decade and I just love it when I learn a new trick.

Perhaps you are working on a command line script and want some feedback, but you’re output buffering to generate a fancy report (or something).  You can bypass the output buffering with this little trick

<?php

ob_start();

echo "BOOM!\n";

fwrite( STDOUT, "You smell funky\n" );

echo ob_get_clean();

Result:

You smell funky
BOOM!

Chromedriver doesn’t run in tmux and here’s how to fix it

Aw, Snap ScreenshotIf you are attempting to run Selenium using the Chromedriver while in a tmux session, you may have encountered some issues with chromedriver.  Specifically, this error:

Aw, Snap!

Something went wrong while displaying this webpage. To continue, reload or go to another page.

If you’re seeing this frequently, trie these suggestions.

A simple solution is to just execute the Selenium jar in a shell session outside of your good friend, tmux.

java -jar ~/bin/selenium-server-standalone-2.33.0.jar -browserSessionReuse -Dwebdriver.chrome.driver=bin/chromedriver

One of my friends, however, alerted me to this article that has a solution:

  • Get Homebrew, if you don’t already have it.
  • brew install reattach-to-user-namespace
  • Add the following line to your .tmux.conf file: set-option -g default-command "reattach-to-user-namespace -l zsh" (replace zsh with bash if you use that)

This fix also resolves the issue that prevents pbcopypbpaste, etc from working in tmux!

Preparing a Site for SOPA Blackout with .htaccess

BorkWeb, like a number of other sites, will be going black this Wednesday as a protest to SOPA.  Legends of the Sun Pig has an excellent article on this exact topic.  Martin writes:

Google recommends using HTTP 503 “Service Unavailable” status codes. The 503 code indicates that the service (or page, or site) is temporarily unavailable, but that it is expected back again soon. This is better than using the 404 (not found), 302 ( moved temporarily), or 301 (moved permanently) codes, because it tells web crawlers that they should just come back and try again later.

Because I have no desire to manually make the cut-over to a SOPA Blackout .htaccess file at midnight (because I’m lazy), I took his .htaccess settings and made a modification to enable the settings for the tomorrow.  Here’s what I have:

<IfModule mod_rewrite.c>

# =====================
# SOPA Blackout
# =====================

# Set a custom error document for 503 errors
ErrorDocument 503 /503_sopa.html

# Cause all requests (except images) to generate a 503 error,
# which will produce the custom 503 error document
RewriteEngine on
RewriteBase /
RewriteCond %{ENV:REDIRECT_STATUS} !=503
RewriteCond %{REQUEST_URI} !\.(jpe?g?|png|gif) [NC]
RewriteCond %{REQUEST_URI} !robots\.txt$ [NC]
RewriteCond %{TIME_YEAR} ^2012
RewriteCond %{TIME_MON} ^01
RewriteCond %{TIME_DAY} ^18
RewriteRule ^ - [L,R=503]

# =====================
# NOT SOPA Blackout
# =====================

# My other rewrite magic goes here.
</IfModule>

Additionally, I’ve shamelessly stolen the php.net SOPA 503 page because it is awesome.

Vim Undo Magic

Ever have a time when you are happily editing a script in vim and you realize you made a mistake over the course of editing? Luckily, Vim supports back in time undos.

You want to go back 10 minutes?

:earlier 10m

You want to go forward in time by 5 seconds?

:later 5s

Sweet cuppin’ cakes that’s ballsy. Armed with this tool, you step forward and backwards in your undo/redo adventure, you make an accidental edit. Whoops. Now all the code you’ve edited in the 10 minutes that you rolled back with the handy-dandy <code>:earlier</code> command is gone…right?

Nope! Undo branching is where the real awesomeness of Vim shines. If you realize your mistake, you can find a list of undo branches like so:

:undolist

Which will show you something like this:

number changes when saved

3 3 08:59:35
4 2 09:00:13

To jump to one of those branches, you can type:

:undo 3 or :undo 4

I <3 Vim

(via Life Hacker)

Sites Not Reachable After Linode Restart

I have recently moved the majority of my sites over to my CentOS Linode VPS and I was experience some load issues that prevented me from gaining SSH access.  As such, I decided to restart my VPS.  After the restart, I found that my sites were not reachable…lame.

First, I checked the firewall found here:

/usr/bin/system-config-securitylevel-tui

So…the firewall was fine.  Next, I attempted to restart the network via:

/etc/init.d/network restart

I was surprised to receive the following error:

Bringing up interface eth0: Device eth0 has different MAC address than expected, ignoring. [FAILED]

Alrighty…bizarre.  So with the help of this article, I was able to determine that eth0’s MAC address:

/sbin/ifconfig eth0

was different than the MAC address found in:

/etc/sysconfig/network-scripts/ifcfg-eth0

A simple edit to the above file and a quick network restart solved my problem and brought my sites back up! w00t!

Platypus Mascot: A Plymouth State April Fool’s Day

Yesterday (April Fool’s Day) I had a little fun and launched a prank on the entire Campus Community of Plymouth State University. The prank? PSU’s portal received a makeover in order to announce a change of the campus’ Mascot from Panther to noble Platypus due to trademark issues.  Results?  Awesome.

Before our users logged in, they were met with a happy Platypus:

A groovy platypus login

A groovy platypus login

Once logged in, the users’ eyes were attacked by custom header complete with Platypus and sun flare that read: “Announcing the new Plymouth State mascot!”

Announcing the new Plymouth State Mascot!

Announcing the new Plymouth State Mascot!

Oh, but it didn’t stop there. You can’t just change a campus’ mascot without some explanation, so forced into the top right of everyone’s layout was a nice portal channel to detail the mascot change.  It read as follows:

Plymouth State has been proud to display the Panther as the University Mascot for many years but effective June 1st, 2009 the Panther will be retired.

Why the new Mascot?

Due to recent trademark disputes, PSU has been asked to select a new symbol for the University. While the change may come as a shock to some, change is a great thing! The adoption of the new mascot is a refreshing and invigorating change that we hope will inspire the campus as the Panther does.

The selection process for the new mascot was a lengthy one where we reviewed over 75 animals that were submitted by the campus community in the recent poll sent out to all students! The top contenders were: Newt, Badger, Elk, Moose, Platypus and Narwhal.

After much discussion, we are excited to announce that the Noble Platypus will be the new mascot!

Why the Platypus?
platypusThere are many attributes of the Platypus that resonate well with Plymouth State ideals. The following were the deciding factors:

  1. Mammal: As we planned the transition from the Panther to the new mascot, the desire that the new animal remain mammalian in nature rang clear with the selection committee. The Platypus fits the bill! (Yes, that was a pun)
  2. Versatile: The Platypus is an extremely versatile mammal which represents Plymouth State’s versatility in it’s educational, athletic, and extra-curricular programs.
  3. Egg Laying Semi-Aquatic Monotreme: The fact that the Platypus is the only semi-aquatic monotreme that lays eggs truly makes it unique. Uniqueness is an attribute in our students that we prize greatly and believe each and every one of you stand out from the crowd.
  4. Venomous: Venom in ankle spurs. This is just an extra bonus.

A change like this cannot be complete without gauging user opinions, so a poll was put together that received almost 1200 votes in 24 hours!

myPlymouth April Fools Day Poll

myPlymouth April Fool's Day Poll

Various end offices received a number of calls from end users ranging from excitement that PSU played an April Fool’s Day prank to frustration that we were switching away from the Panther (those people obviously didn’t know it was the 1st). All in all, I would consider this a successful holiday!

Now…what should I do next year?

Guest Lecture: JavaScript, Ajax & DOM Manipulation

Zach has asked me to give a JavaScript guest lecture in his Web Programming class. We’ll cover: JS basics, node manipulation, DOM traversal, AJAX, JavaScript libraries, and myPlymouth implementations of those topics. Here are the slides (get the .ppt here):

A few resources that are mentioned:

Note: this is an updated talk on the workshop I led two years ago

CSS Selector Browser Support

As many web developers know, CSS support is highly varied amongst browsers. I often find myself hunting for which selectors are more heavily supported. As such, I thought I’d post a direct link to a quality resource here so I wouldn’t have to hunt anywhere besides on BorkWeb.

Here’s some decent resources:

Oracle 10g: Using The Returning Clause With ADOdb

Plymouth State University uses Oracle heavily due to its Student Information System of choice – SungardHE Banner. As such, I play around in Oracle a lot (sometimes a lot more than I’d like) and I occasionally find functionality that seems more cumbersome than it should.

One such item is selecting the last inserted value on an auto-incrementing column.

Historically, when you are inserting into a table with auto incrementing values (via a sequence) you have always been able to grab the last value with a simple SELECT statement (line 22):

-- setup a table
CREATE TABLE bork (id INTEGER NOT NULL PRIMARY KEY, data VARCHAR2(10) NOT NULL);

-- create the sequence
CREATE SEQUENCE sq_bork INCREMENT BY 1 START WITH 1; 

-- create a trigger for auto-incrementing the sequence'
CREATE OR REPLACE TRIGGER tr_sq_bork
BEFORE INSERT
ON bork
REFERENCING NEW AS NEW
FOR EACH ROW 
BEGIN
SELECT sq_bork.NEXTVAL INTO :NEW.id FROM DUAL;
END;
/

-- insert a record into the table
INSERT INTO bork (name) VALUES ('Matt');

-- retrieve last inserted id
SELECT sq_bork.CURRVAL FROM dual;

As you see there, two statements must be executed to get that new id. The INSERT and the SELECT. Well, as of Oracle 10g you can utilize the RETURNING clause like so:

INSERT INTO bork (name) VALUES ('Matt') RETURNING id INTO i_id;

That statement inserts a record into “bork” and returns the value of “id” into the “i_id” variable. Pretty sexy and all with one DML statement. Here’s what we do at Plymouth to utilize the RETURNING clause with the PHP library ADOdb:

< ?php
//do your database object initialization here:
//$db = new ADONewConnection...

$sql = "BEGIN INSERT INTO bork (data) VALUES ('Matt') RETURNING id INTO :i_id; END;";
$stmt = $db->PrepareSP($sql);
$db->OutParameter($stmt, $inserted_id, 'i_id');
$db->Execute($stmt);
?>

Yup. 4 lines of PHP but only 1 statement sent to the database! I’d take the extra lines any day over the latency of data retrieval.