Stuck Inside of Mobile With the Memphis Blues Again…

This is not what my front yard looks like today, but it is my front yard. It’ll be warm again sometime soon won’t it?

Warmth

Advertisements

PHP + BBEdit + RegEx for code generation get/set functions

Here’s a handy way to generate getter/setter functions. I use BBEdit, but since this is based on Regular Expressions it could be done in just about any code editor.

Say you start a class and have defined the following private member variables:

private $ip_range_id;
private $subscriber_id;
private $low_ip;
private $high_ip;

The next thing I commonly would want to add to my class is a public function for each member variable that can be used for either getting or setting its value. So for $high_ip, I might want a functiont that looks something like this:

public function high_ip($high_ip=false)
{
    if($high_ip) {
        $this->high_ip = $high_ip;
        return $this->high_ip;
    } else {
        return $this->high_ip;
    }
}

This way if I have instantiated an object from this class called $ipr I can get the current value of the private $high_ip like this: $ipr->high_ip() and if I want to set the value of $ipr‘s $high_ip to be '127.0.0.1' I can do it like this: $ipr->high_ip('127.0.0.1').

Ok, but what about those RegExs and the code generation bit?

Since the getter/setter functions generally start off very similar, they are ripe for templates and templates are a good place to build generators. I’ve seen many approaches, and they have their benefits but this is so quick and easy I thought it might be helpful to someone.

1. Copy the private member declaration from the class into a temporary document (BBEdit’s “Scratchpad” is great for this, as is Emac’s *scratch* buffer).

2. Open the “Find…” dialog, and enter this RegEx in the “Find” field:

^private \$([\w]+);$

3. Paste this into the “Replace” field:


public function \1($\1=false)
{
    if($\1) {
        $this->\1 = $\1;
        return $this->\1;
    } else {
        return $this->\1;
    }
}

4. Make sure “Grep” and “Wrap around” are checked off, and then press the “Replace All” button, and voila!


public function ip_range_id($ip_range_id=false)
{
    if($ip_range_id) {
        $this->ip_range_id = $ip_range_id;
        return $this->ip_range_id;
    } else {
        return $this->ip_range_id;
    }
}
public function subscriber_id($subscriber_id=false)
{
    if($subscriber_id) {
        $this->subscriber_id = $subscriber_id;
        return $this->subscriber_id;
    } else {
        return $this->subscriber_id;
    }
}
public function low_ip($low_ip=false)
{
    if($low_ip) {
        $this->low_ip = $low_ip;
        return $this->low_ip;
    } else {
        return $this->low_ip;
    }
}
public function high_ip($high_ip=false)
{
    if($high_ip) {
        $this->high_ip = $high_ip;
        return $this->high_ip;
    } else {
        return $this->high_ip;
    }
}

Checking IP Ranges for Sanity / Validity

This doesn’t cover a lot of cases so it is really a sanity check for IP Ranges. It takes two IP addresses a low one and a high one and makes sure they are valid IPv4 addresses and it take a look to make sure (at least I hope it makes sure, anyone want to help me out here?) the low_ip is ‘lower’ than the high_ip.

This is used by some code that allows a user to specify an IP address range and then when the application ‘sees’ a client coming from within a known range, it associates the client with the ‘user’ who set up the range. (Think library systems that restrict content via institutional IPs)

$low_ip = '18.0.0.0';
$high_ip = '18.255.255.255';

if( validate_ip_range($low_ip, $high_ip) ) {
    print "yes\n";
} else {
    print "no\n";
}
function validate_ip_address($ip)
{
    if( ($long_ip = ip2long($ip)) !== false) {
        if($ip == long2ip($long_ip)) {
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

function validate_ip_range($low_ip, $high_ip)
{
    if(validate_ip_address($low_ip) && validate_ip_address($high_ip)) {
        $long_low_ip = ip2long($low_ip);
        $long_high_ip = ip2long($high_ip);
        if( ($low_ip == long2ip($long_low_ip)) && ($high_ip == long2ip($long_high_ip)) ) {
            if($long_low_ip <= $long_high_ip) {
                # now check that 1st octet matches in each ip (18.* == 18.*)
                $low_octets = explode(".", $low_ip);
                $high_octets = explode(".", $high_ip);
                if($low_octets[0] != $high_octets[0]) { return false; }
                # for each of the remaining 3 octets, low_ip's octet <= high ips.
                # e.g. 18.151.1.0 18.151.1.255
                # 18.57.0.41 - 18.57.0.100
                for($i = 1; $i < 4; $i++) {
                    if($low_octets[$i] > $high_octets[$i]) { return false; }
                }
                $num_ips = ( sprintf("%u", $long_high_ip) - sprintf("%u", $long_low_ip) );
                if($num_ips > 65535) { echo "warn: above a class C address space\n"; }
                # if we made it this far, should be a valid rang for our purposes
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    } else {
        return false;
    }
}

Attached is a text file disguised as a .doc with the test “harness” for this function and the function suggested by tevis below. For malformed IP ranges such as $low_ip = ‘18.0.0.14’ and $high_ip = ‘18.255.255.1’; the suggestion below doesn’t seem to work, but the cumbersome process does correctly indicate that there’s a problem with that kind of IP range.

Configure OpenX Maintenance Scripts on SliceHost

Setup:

  • SliceHost 1gb RAM Xen VPS x86_64
  • CentOS 5.2
  • MySQL 5.0.45
  • PHP 5.1.6 (cli)
  • Apache 2.2.3
  • OpenX 2.6.3

Unless you love vi, set your environment’s EDITOR first. For me, this is the most important part of the process. I hear the cool kids use nano these days. I work at MIT so I feel like I have to use Emacs.¬†

edit ~/.bash_profile and add these lines
EDITOR=/usr/bin/emacs
export EDITOR

Then edit your crontab file and add a line like this to it:
crontab -e
30 10 * * * /usr/bin/php /var/www/i.mitsmr.com/openx/scripts/maintenance/maintenance.php i.mitsmr.com

That will run the maintenance script once per day at 10:30pm. Check your crontab log for any errors:
sudo tail /var/log/crontab

Oh, and OpenX pushed 2.6.4 update out yesterday. Take one thing off the todo-list, add something new right back on! Sheesh.