Secret Santa Name Picker Script

Monday, November 22nd, 2010

In the last ten years we’ve been gathering for our annual Pelago holiday party we’ve developed a fun Secret Santa tradition. The theme of the gift exchange is t-shirts. Each person picks a name from a hat to find out the lucky (or unlucky, depending on how you look at it) recipient of a hand-selected t-shirt. With one employee going remote and us being a technology company, it seemed somewhat Ludditean of us to continue picking strips of paper from a box.

This year we automated the process. We wrote a PHP script that would pick the names for us. It starts with an array of email addresses, matches them up in a random order and then emails each person their recipient. And it makes sure no one gets the same person. Take a look at the script below. It’s just a few simple lines of code. Feel free to use it for your next Secret Santa assignments. The basic code is below. Just plug the results in to your favorite email software to secretly distribute the results.


<?php

$emails = array(
     'name1@yourcompany.com',
     'name2@yourcompany.com',
     'name3@yourcompany.com',
     'name4@yourcompany.com',
     'name5@yourcompany.com',
);
$matches = array();

// randomize a key => value array
$givers = range(0,count($emails)-1);
$givees = range(0,count($emails)-1);

do {

     shuffle($givers);
     shuffle($givees);

     $matches = array_combine($givers, $givees);

     foreach ($matches as $er => $ee) {
          if ($er == $ee) continue 2;
     }

     break;

} while (true);

foreach ($matches as $er => $ee) {
     echo $emails[$er] . " gives to " . $emails[$ee] . "\n";
}

?>

Face detection in pure PHP

Thursday, June 25th, 2009

Face detection in pure PHP

Technical description.

PHP crons, linux, and the hostname

Thursday, May 28th, 2009

When running PHP as a cron, the $_SERVER['HOSTNAME'] variable is not set, nor are any other variables that will identify which server your cron is running on. This can be problematic if you are running the same cron on multiple servers, such as in a load balanced environment, and you need the cron to report back or log information about the server on which it ran.

Here is some code for getting the hostname value from your linux network configuration, assuming you have setup /etc/sysconfig/network properly.


//get hostname info from /etc/sysconfig/network
preg_match('/HOSTNAME=(.*)/', file_get_contents('/etc/sysconfig/network'), $network);
$hostname = split("\=", $network[0]);
echo $hostname[1]; //this equals the value of your HOSTNAME

Installing Libmcrypt on a Godaddy Virtual Dedicated Server

Friday, July 11th, 2008

UPDATE: Using this article at http://www.hagrin.com/315/installing-mcrypt-a-godaddy-linux-virtual-dedicated-server-vds I was able to install mcrypt on a Godaddy Virtual Dedicated Server in just a few steps:

  1. SSH into your VDS with your favorite SSH client or the SSH Java applet offered by GoDaddy.
  2. Login with your credentials.
  3. Su to the root user.
  4. Type “yum install libmcrypt”. Say yes to the prompts.
  5. Type “yum install php-mcrypt”. Say yes to the prompts.
  6. Restart the server using “/usr/sbin/apachectl restart”.

 

We recently deployed a web site using GoDaddy’s virtual dedicated server. Everything about the default PHP installation was fine, except that libmcrypt was not available. When I asked the godaddy support staff “How do we enable libmcrypt for PHP?” their response was far from helpful:

Thank you for contacting Server Support. Unfortunately 3rd party installations and configurations are not supported.

Rather than argue with the support team about what constitutes a 3rd party installation, I decided to google around and see if I could do it myself. Hours later, I succeeded. Here are the steps for installing libmcrypt:

  1. su root
  2. yum install gcc-c++
  3. yum install lex
  4. yum install libxml2
  5. yum install libxml2-devel
  6. yum install flex
  7. wget http://downloads.sourceforge.net/mcrypt/libmcrypt-2.5.8.tar.gz?modtime=1171868460&big_mirror=0
  8. tar -xzvf libmcrypt-2.5.8.tar.gz
  9. cd libmcrypt-2.5.8
  10. ./configure
  11. make
  12. make install
  13. wget http://museum.php.net/php5/php-5.1.6.tar.gz
  14. tar -xzvf php-5.1.6.tar.gz
  15. cd php-5.1.6
  16. ./configure –with-mcrypt=shared,/usr/local/lib
  17. make (after running ‘make’, DO NOT RUN ‘make install’)
  18. cp modules/mcrypt.so /usr/lib/php/modules/
  19. Add a file /etc/php.d/mcrypt.ini
    ; Enable mcrypt extension module
    extension=mcrypt.so
  20. /usr/sbin/apachectl restart

That’s it! To confirm a successful install, just run phpinfo() and look for the mcrypt section

Setting locale to tr_TR (Turkish) lowercases class names

Thursday, April 3rd, 2008

So I was working away at localizing some pages and for some reason they all worked except tr_TR. What was the problem? The server had an outdated PHP installation with a bug that lowercases class names which ends a fatal error.

Why it it so? After some investigations I came across this bug and came to the conclusion that in the Turkish language, the latin i is not equal to capital latin i.

AWESOME!

WTF!? preg_replace() returns null?

Friday, January 25th, 2008

On one of our sites were were running into a problem when we tried to pass HTML content from a database through an email obfuscation function to prevent spiders from scraping our clients’ email addresses. We quickly discovered that some of the longer pages were showing up completely blank. The preg_replace() function we were using to run the obfuscation code on email addresses was returning null. After some hunting I found the answer.

(more…)

ISO Week and Year in PHP and PostgreSQL

Thursday, January 10th, 2008

The new year always brings with it a few small things that go bump in the morning. 2008 was no different. Intervals started behaving oddly on New Year’s Eve morning — the default timesheet was a year behind schedule. What happened?

In our PHP code, we are using the ISO-8601 week number of year, as specified on the PHP date function page, but we weren’t using ISO-8601 for the year. The ISO-8601 week number specifies the last monday of a year as the first week of the new year, if that new year begins before thursday. Intervals thought it was the first year of 2007!

In PHP, the fix was as easy as converting all instances of date(‘Y’) to date(‘o’), according to php.net:

ISO-8601 year number. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead. (added in PHP 5.1.0)

That fixed everything on the PHP side of things. But next we had to dig into the SQL queries and get them to use the ISO Year.

Snag.

PostgreSQL 8.2.5 doesn’t support ISO Year in the Extract function. EXTRACT(ISOYEAR, timestamp) is being included in PostgreSQL 8.3, as specified here in the RC1 documentation. But PostgreSQL 8.3 hasn’t been released yet, and we needed to fix things immediately.

Our final PostgreSQL fix was to instead use the TO_CHAR(timestamp, ‘IYYY’) function. It’s not ideal to be using a string formatting function for data comparisons, because it slows down some of the queries. But we had to trade some performance to get things working properly again in the new year. As soon as the PostgreSQL developers release a stable version of 8.3, we’ll change our queries back to using EXTRACT(ISOYEAR, timestamp).

PHP 4 end of life announcement

Friday, July 27th, 2007

The PHP team has announced that they will discontinue support for PHP 4. Now it’s really time to stop procrastinating and upgrade.