DeArmond.net

Thoughts, adventures, projects, and photography by Shawn DeArmond

Launching Circle of Gifts on Drupal

November 17, 2013 - 7:13pm -- Shawn

This past week, I launched a cool new web site on Drupal. It's called Circle of Gifts, and it's a tool to help families and friends make their holiday shopping easier. Users build their wish list on the site, and their Friends "claim" items so others know not to buy that gift. I originally built it for my family, but have since expanded it and it's now open to the public.

There were a lot of moving parts and a lot of challenges to overcome in building a social network on Drupal. Let's look at some of them:

Claiming Gifts

The core functionality of this site is that people need to be able to create their wish list, and other people need to "claim" the gifts. Enter the Flag module. Flag's slick ajax system made it easy to mark a gift as claimed, but it didn't end there. Only one person can claim a gift, and nobody else should be able to unclaim it. Neither global nor standard flag functionality would work. Fortunately, I was able to take the work Jen Lampton did on the Flag Limit module, upgrade it to Drupal 7, and add the functionality I needed. Problem solved!

Flag was also used for two other pieces of functionality on the site: to mark a gift as "not wanted anymore", to mark a gift as "Bought" once it's on your Shopping List.

To be honest, the biggest problem we had with Flag, and it's still something we're tossing around, is how to label the links. Here's what the links look like now:

 

Claimed

Bought

Don't Want

Flag link

Flag link description

Click to claim

Click to mark this gift as bought.

Remove this item from my gift list

Flagged message

You have claimed this gift.

You have bought this gift.

You no longer want this item

Flag unlink

Flag unlink description

Click to release your claim on this gift. 

Click to mark this gift as not bought 

Add this item back to my gift list. 

Unflagged message

This gift can now be claimed. 

This gift is not bought. 

This item is now back in my gift list. 

The trouble with flag link text is that it is simultaneously trying to display current state and an action. By making the links buttons, it is moving towards being an action as opposed to a state. "Claim" and "Release" icons work pretty well, as do the "Remove" and "Add Back". But I'm still not thrilled about "Bought" and "Not Bought", as the text is not an action word, but rather a state. The problem is that the act of actually purchasing the gift is outside the control of the site. It just links to Amazon. This is just checking it off your Shopping List. I'm still working on that one.

Birthday Views

This one SEEMS so simple: Standard Date field for users to enter their birthdate (including year). I need a view that shows all my friends, sorted by which birthday is coming up next. Just sorting by the field doesn't work, of course, because it shouldn't take year into consideration. Also, if today is November 17, the birthdays in December should come before the birthdays in January, so just sorting by the day of the year isn't going to work either. Also, if the birthday field is blank, it should put them at the end of the list.

I ended up implementing hook_views_query_alter(). Here's the function:

/**
* Implements hook_views_query_alter().
*/
function mymodule_views_query_alter(&$view, &$query){
  if ($view->name == 'mymodule_birthdays') {
    foreach ($query->orderby as $key => $sort) {
      $newkey = $key + 2;
      $query->orderby[$newkey] = $sort;
    }
    $query->orderby[0]['field'] = "ISNULL(field_data_field_mymodule_birthday_field_mymodule_birt)";
    $query->orderby[0]['direction'] = "ASC";
    $query->orderby[1]['field'] = "((DAYOFYEAR(field_data_field_mymodule_birthday_field_mymodule_birt) - DAYOFYEAR(NOW()) + 365 ) % 365)";
    $query->orderby[1]['direction'] = "ASC";
  }
}

Take a look at your query to see what it's labeling the birthday field.

The first $query->orderby looks to see if the field is empty, and puts the empty ones at the end. The second $query->orderby takes the day of the year of the birthday, subtracts the day of the year of today, adds 365 so we won't have any negatives, and then finds the remainder when dividing by 365. Totally works. Yay math! (Some math wiz wanna tell me what's going to happen in 2016 for leap year? Sorta wondering.)

Circle of Gifts had plenty more obstacles that were overcome, but I finally launched it. I invite you to create an account, poke around, and maybe it'll be useful to you like it is for my family.

Comments

Submitted by test on

rather than bought - not bought (sounds out) I'd consider purchased and not purchased

Comments

Submitted by test on

rather than bought - not bought (sounds out) I'd consider purchased and not purchased