Archive for Programming

SmugMug Tweaks

SmugMug Admin Rating Sample

Lately, I’ve been working on some SmugMug tweaks to take advantage of their offer of a free lifetime account for developers who use their API. The first one was a quick hack which uploads some recent SmugMug photos to your Flickr account. This allows people who switched to SmugMug to still keep up with their Flickr network. More information is available on the project’s page.

The second and more interesting one is some JavaScript that adds the ability for SmugMug users to rate their own photos. This is the first of two projects to aid my work flow. Eventually I want to be able to upload a bunch of photos in a private album, rate them, and then in one fell swoop move all photos with a rating higher than X to a public album.

I provide two installation options which both pull the script from my server and inject it into the pages. This should allow for invisible upgrades. Savvy or cautious users can install it other ways.

Another interesting aspect of this project is its integration with SmugMug’s API. First, we’re using the API on SmugMug’s own site. This isn’t the typical use case of a photo site’s API. Secondly, the script gets proper API authorization behind the scenes, without asking the user for any information. Provided that the user is already logged in to SmugMug’s site, then my script gains that user’s credentials when interacting with API. This is not evident in the API docs and requires a bit of a hack.

Any users should be aware of security concerns whenever external JavaScript is inserted into your page.  Protect yourself as you see fit.

Comments

ActiveRecord in PHP

I’ve been meaning to release this code for quite some time. I’ve finally had a bit of time and motivation to sit down and take care of it. Ever since I started working with Ruby on Rails, I would cringe whenever I had to write yet more PHP code to do simple CRUD actions. Furthermore I really enjoyed the Rails syntax that you use to interact with its implementation of the ActiveRecord pattern. As such, I went forward and built a clone using PHP5. So far it has been used for a few projects and has been a joy to use.

Props to my employer, Gospel Communications, who allowed me to spend some time on this during work hours, as well as give me full copyright of the code.

More information and documentation over on the project’s home page.

Comments

PHP and Named Parameters

Since working with Ruby on Rails, I’ve become much more conscious about how my code looks. Occasionally, when working with PHP there are things that are a part of the language that tend to make my code look ugly or just not very clear and succinct.

One such case is when defining arrays, particularly nested associative arrays. PHP makes working with arrays fairly handy, however I always shudder when I have to create / populate an array explicitly. Some of the code I’m working with lately uses associative arrays as a way to have named parameters in PHP. Here’s some example code that uses associative arrays in this way:

  1. $p1 = new Person(‘Luke Baker’,
  2.      array(‘home_phone’ => ‘555-5555′, ‘cell_phone’ => ‘555-5551′));
  3. $p2 = new Person(‘John Doe’,
  4.      array(‘cell_phone’ => ‘555-5531′, ‘email’ => ‘john@doe.com’);

Named parameters let us accept lots of different types of information, without splitting them up into individual parameters and having to remember which order the parameters are in. I can handle home_phone, cell_phone, and email in the person constructor and the call to the constructor doesn’t have to worry about the order of parameters or filling in null values for information it doesn’t have.

The above example doesn’t look too ugly, but we also aren’t stretching the named parameters very much. Here’s a slightly messier example:

  1. $p3 = new Person("John Calvin", array(‘dates’ => array(‘birth’ => ‘July 10, 1509′, ‘death’ => ‘May 27, 1564′)));

We could break it into different lines, which doesn’t look too shabby:

  1. $p3 = new Person("John Calvin", array(
  2.     ‘dates’ => array(
  3.         ‘birth’ => ‘July 10, 1509′,
  4.         ‘death’ => ‘May 27, 1564′
  5.     )));

Another option, might be to use JSON to represent that associative array. We could have our constructor decode the second parameter from JSON if it looks like it might be JSON. Once it is decoded, we’re back to an array representation in PHP, which is what we started with. In other words, we can easily allow our constructor to accept either JSON or an array as the second parameter. Then we could write the call the to constructor as follows:

  1. $p3 = new Person("John Calvin",
  2.     ‘{"dates" : {"birth" : "July 10, 1509", "death" : "May 27, 1564"}}’);

Maybe I’m silly, but I like the look of the JSON example a bit better. I certainly won’t be using JSON everywhere I declare arrays, but here and there I find it useful. What do you think, is it worthwhile to support JSON in this way?

Comments

The static keyword in PHP5

With PHP5, PHP introduced some more robust object oriented capabilities to the language. I’ve been diving into this quite a bit lately and learning a lot. I figured all the stuff I discovered about the static keyword would be enough fodder for a post. Most of this information can probably be gleamed straight from the docs, but I for one didn’t really soak up the denseness of the documentation my first few times around.

Static Members

What isn’t immediately obvious, is that static members are shared among all the instances of the class that has the static member. In other words, it is like a global variable for that class and instances of that class. While you can’t access a static member directly from an instantiation of the class, you can create methods that access or manipulate the static member. Time for a quick example.

  1. class Foo {
  2.   static $var = 0;
  3.   function increment() { self::$var++; }
  4.   function get() { return self::$var; }
  5. }
  6.  
  7. $f1 = new Foo();
  8. $f1->get();  // returns 0
  9. Foo::$var; // returns 0
  10. $f1->increment();
  11. $f2 = new Foo();
  12. $f2->get();  // returns 1
  13. $f2->increment();
  14. $f1->get();  // returns 2
  15. Foo::$var; // returns 2

Now, the other interesting find is that the static member is global not only to that class and instances of that class, but also all sub-classes and instances of those sub-classes. You can prevent this propagation down inheritance tree, by declaring the static member as private or by redeclaring that static member inside the sub-classes, as well as the methods that work on the static method.

  1. class Foo {
  2.   static $var = 0;
  3.   function increment() { self::$var++; }
  4.   function get() { return self::$var; }
  5. }
  6. class Bar extends Foo { }
  7. Foo::$var++;
  8. Bar::$var;  // returns 1

Static Methods

The main area that I got hung up with static methods was using inherited static method calls. For the work I was doing, I wanted to be able to call a static method and within the static method know which class this method was called on. Unfortunately, everything I tried didn’t work.

  1. class Foo {
  2.   static function get_my_class() { return get_class(); }
  3.   function get_my_class2() { return get_class($this); }
  4. }
  5. class Bar extends Foo {}
  6. Bar::get_my_class();  // returns ‘Foo’
  7. $b = new Bar();
  8. $b->get_my_class2();  // returns ‘Bar’

It turns out that static methods belong to the class in which they’re defined and they have no clue where they got called from. Similarly, the same idea can be applied when thinking about static members. The class that has the actual code, determines what variable is affected. Consider one last example:

  1. class Foo {
  2.   static $var = 0;
  3.   function increment() { self::$var++; }
  4.   function get() { return self::$var; }
  5. }
  6. class Bar extends Foo {
  7.   static $var = 23;
  8.   function increment() { self::$var++; }
  9. }
  10. $f = new Foo();
  11. $b = new Bar();
  12. $b->get(); // returns 0 (Foo)
  13. $b->increment();  // increment Bar’s $var
  14. Bar::$var; // returns 24 (Bar)
  15. $b->get(); // returns 0

Comments (2)