Rss Feed Tweeter button Facebook button Technorati button Reddit button Linkedin button Webonews button Delicious button Digg button Flickr button Stumbleupon button Newsvine button

A Waage Blog

Ruby, Rails, Life

Archive for March, 2011

Wordpress Plugin – track referrers based on url GET parameters using regular expressions

with one comment

First of all, all the credit and thanks to Marios Alexandrou for his wordpress plugin Social Media Alerts for Wordpress, which allows you to set up email notifications when certain query-strings are received to your wordpress site!

For example, if you wish to see when visitors come to your site from Twitter, you can specify a query string of “source=twitter”. When visitors come to your page with this parameter on the URL (ie. http://yoursite.com/?source=twitter) then this will be tracked, and you can be notified by email.

I installed this plugin but besides specifying the literal query-string, I wanted to be able to handle dynamic query-strings based on regular expressions that I could define. For example, I wanted to track all query-strings that matched “http://mysite.com?ref=..”.

This would track visits to anything where the query string matched “ref=…”. For example, “http://mysite.com?ref=twitter”, “http://mysite.com?ref=facebook”, “http://mysite.com?ref=digg”, etc.

Here’s my little bit of code to the plugin to support regular expressions :

# File: social-media-email-alerts.php
# Line: 142
# Replace the existing "get_query" function definition with this:
  function get_query($qs){
          global $wra_sites;

          if ($qs) {
                  $query = explode("&",$qs);

                  foreach($query as $query_string){
                          if(is_array($wra_sites[$query_string])){
                                  return $query_string;
                          }
                  }
                  # Added for regexp matching on query string
                  foreach($query as $query_string){
                          foreach($wra_sites as $key => $val){
                                  if (preg_match($key, $query_string) > 0) {
                                          return $key;
                                  }
                          }
                  }
          }
          return false;
  }

As you can see, it’s just a single foreach block that will match a query-string by regex, and return if found. Now it’s possible to add a rule for /^ref=.+/ that will alert me upon any match to this regular expression.

Written by Andrew Waage

March 24th, 2011 at 5:37 pm

Ruby Multi-level Nested Hash Value

with 5 comments

Often in my Ruby code or Rails application, I will need to find a value in a nested hash. Frequently this also comes in handy when dealing with JSON and parsing JSON to a hash. For example, I might have a hash of user information that looks like this:

user_hash = {:id => 1, :name => 'John doe', :extra => {:birthday => {:month => 11, :day => 16, :year => 1951}}}

Now, when I want to find the birthday year, I have to do something messy like this:

year = user_hash[:extra] && user_hash[:extra][:birthday] && user_hash[:extra][:birthday][:year]

How inconvenient is this?! Every level of the hash I am checking for existence of the hash-key. Here’s a helper method that I use so that I can avoid these verbose statements and get the value I want in 1 line. It adds a ‘hash_val’ method to any hash, and takes in the hash-keys as arguments. If one of the nested hash keys is missing, it will simply return nil.

# I usually define this in an initializer, so it can be used all over my app:
# Eg. Place in config/initializers/hash_val.rb
class Hash
  # Fetch a nested hash value
  def hash_val(*attrs)
    attr_count = attrs.size
    current_val = self
    for i in 0..(attr_count-1)
      attr_name = attrs[i]
      return current_val[attr_name] if i == (attr_count-1)
      return nil if current_val[attr_name].nil?
      current_val = current_val[attr_name]
    end
    return nil
  end
end

Now, getting a nested hash value is so easy!

user_hash.hash_val(:extra, :birthday, :year)
 => 1951

And, if the hash-key does not exist, it simply returns nil:

user_hash.hash_val(:extra, :trouble)
=> nil

Written by Andrew Waage

March 18th, 2011 at 8:27 pm