How Listening to NPR Helped Me At Work

I’m building a really neat little project at work: the ability for users to contact their state or federal legislators for a campaign that my company is running to advocate for/against some issue. A big part of my job includes evaluating specs and making both technical and business recommendations. Here’s a quick list of feedback I gave the our policy team based on my knowledge of American government, mostly garnered through years of listening to NPR.

  • Not all policy is decided by Congress/state legislature. Often, laws cover sweeping concepts and actual implementation is defined by the relevant agency. For example, the Clean Water Act enabled the EPA to set whatever rules it deemed necessary to protect water sources. This project will not encompass emailing agency heads, so that needs to be kept in mind when determining the scope of this new feature.
  • We shouldn’t include the governor/POTUS on the list of legislators to email because they don’t (usually) vote on legislation and therefore a generic email that is sent to all the user’s legislators would be irrelevant and nonsensical.
  • Not every state has a bicameral legislature; Nebraska is unicameral. Therefore, should we wish to limit future state campaigns to one level, we need to code an exception for Nebraska. This affects delivery date and requires specific testing.
  • Some states have different names for their upper and lower levels than House of Representatives and Senate. Before committing to the ability to limit state campaigns to one level, I need to research whether the API we use to retrieve legislator data returns a generic upper/lower/ value or whether I need to code in a map to translate this. This affects delivery date and requires specific testing.

Race Report: 8 Hours of Hell Racing Series – Caloosahatchee East

Date
May 23rd, 2015
Location
Caloosahatchee Regional Park, northeast quadrant
Cost
$100 for a single race; $450 for the series of 5 + championship. Single race entry fees can be applied to the series if you choose to do the rest.
Info
Ultra Signup

I first met Justin when he directed my first (and so far only) 50k back in December. He was a really nice guy and threw a fantastic race, so when he announced that he was going to be the race director for an inaugural series called 8 Hours of Hell, my husband and I knew we had to do it. The premise of the series is exactly what the name says: a series of 5 monthly runs composed of 8 hours of trails, in the south-central Florida heat and humidity. Races start at 10am to maximize misery and are located in various parks in the Lee/Charlotte county area of south-central Florida. Each race has a fully stocked aid station with all the standard ultra goodies, plus a ton of extra ice and water for the heat. Tailwind is the electrolyte of choice for all of Justin’s races.

The first race was two days ago, on Saturday, May 23rd. We were in my favorite trail running park, the same one in which I did my 50k. Matt and I arrived at 9am to the staging parking lot, about 1/4 mile from the race start/finish. We met up with an acquaintance from my tri club, got checked in, talked a bit with other runners, and then got our gear loaded up in the sherpa cars. We brought one large water cooler filled with diluted Osmo for electrolytes, one cooler filled with some sandwiches, watermelon, grapes, ice, and other goodies. Even though Justin always has copious, fantastic food at the aid stations, we just wanted to be conservative to make sure we had our favorites.

The race began on time, with the usual non-existent trail fanfare (“Ok, you can go now”) with 19 out of 20 runners making it to the start. One woman was unable to make it last-minute. We were running a 4.75 mile loop, mostly single track. The route was about 30% flat, open terrain, 30% flat but very rocky or rooty areas, and 40% short but steep and very rocky/rooty black diamond mountain bike hills. It also had rained the night before so some of the hills were a bit slippery with clay mud. Because this course was so long, we had a second mini aid station with ice, water, and Tailwind at the start/end of the most difficult part of the course (the Far East and new extension loop).

I had promised my coach that I would take it easy so I wouldn’t ruin my IMFL training. Her rule was that if I was too tired to do a bike ride the next day, then I was banned from doing the rest of the series. My goal was to do 26.2 miles, a brisk walking pace. Super easy, right? HAHAHHAHAHAHHAHAHAHAHAHA! My first loop was fine, I mostly walked with some guy I met on the trail and Matt, who caught up to us in the last mile. It started getting hot during the second loop, especially out in the open. I’m estimating a “real feel” of close to 100. My third loop was completely miserable, but I met a really nice couple who had just done the Keys 100 a week before so we ran/walked together. I gave the girl some grapes that I had been hoarding and she loved them, so for the 4th lap I decided to be brilliant and carry a whole baggie full of them for us to eat in Far East.

So there we were, 5 hours into the race (3pm). I was holding a paper bag full of these cold, crisp, perfectly sweet grapes for us to share. Just as we got past the Far East aid station to start the loop, the bag ripped open and all the grapes fell to the ground. We stopped, looked at each other in horror, looked at the ground. Looked back at each other, back at the ground, and then suddenly both of us were on our hands and knees desperately picking up grapes and shoving them in our mouths. Best grapes I’ve ever eaten in my life.

By then, clouds had come in and we were starting to hear thunder in the distance, getting closer every minute. The temperature dropped enough that I stopped sweating. Now, I’m terrified of lightning but I went out on my 5th lap anyway. When I got back to Far East, I met up with the lead woman and we discussed the weather situation. We had the option of doing a half loop by skipping Far East, with the caveat that once we shortcutted, that was it for the race. She and I decided that it wasn’t worth the risk even though we were under thick tree cover, and I was tired and didn’t want to push it, so we went back and reported our cutoff. Turns out that a message had been lost that the storm was moving away from the race, but it doesn’t matter, it was time to stop for me.

I ended up with a total of 21.75 miles in 6.5 hours. Given that the lead woman only did a 50k, I’m really content. I ended up 11th out of 19 people who started, but I was able to do a hard 35 mile ride the next day. More importantly, I had a lot of fun, made a couple new friends, and am looking forward to the next race!

Hiding Exposed View Filter Form Elements

I have a task in which I need to create an exposed filter for a View and then set its value via code based on the value of another field. Here’s how to hide a View’s exposed filter form element, which is slightly different than how you do it for other forms.

/**
 * Implements hook_form_FORM_ID_alter().
 */
function MY_MODULE_form_views_exposed_form_alter(&$form, &$form_state, $form_id) {

  switch ($form_state['view']->name) {

    // Admin content list
    case 'NAME_OF_VIEW_WITH_EXPOSED_FILTERS' :

      $form['MY_EXPOSED_FILTER_FIELD']['#access'] = FALSE; // This is the normal way
      $form['#info']['MY_EXPOSED_FILTER_FIELD']['label'] = NULL; // This hides the label
      
      break;
  }

}

Drupal: Programmatically Create Horizontal Tabs in a Custom Form

We happen to be in an engineering R&D sprint at work and I’m working on a widget maker so users can embed a small snippet into their blog and show off their latest reviews and so on. I’m working on the widget generator UI, which is a custom form that will call some JS on submit to output the desired markup. I wanted each widget type to be in its own horizontal tab, a la Twitter’s widget configurator (must be logged in to view. If this were a content type, it would be easy enough to group fields into a horizontal tabs group and child horizontal tabs, but the form is completely made from scratch. After much trial and error, here’s the minimum necessary to create horizontal tabs.

/**
 * Form callback.
 */
function csm_api_widget_form($form, &$form_state) {

  // Horizontal tabs container
  $form['group_tabs'] = array(
    '#type'     => 'horizontal_tabs',
    '#attached' => array('library' => array(array('field_group', 'horizontal-tabs'))), // Converts fieldsets into tabs
  );

  // My Reviews tab
  $form['group_user_reviews'] = array(
    '#type'  => 'fieldset',
    '#title' => t('My Reviews'),
    '#group' => 'group_tabs',
  );

  // Field - username (hardcoded)
  $form['group_user_reviews']['name'] =	array(
    '#type' => 'textfield',
    '#title' => t('My text field'),
    '#group' => 'group_user_reviews',
  );

  // Field - submit button
  $form['group_user_reviews']['submit'] = array(
    '#type'  => 'button',
    '#value' => t('Create My Reviews Widget'),
    '#group' => 'group_user_reviews',
  );

  // My Favorites tab
  $form['group_favorites'] = array(
    '#type'  => 'fieldset',
    '#title' => t('My Favorites'),
    '#group' => 'group_tabs',
  );

  $form['group_favorites']['submit'] = array(
    '#type'  => 'button',
    '#value' => t('Create My Favorites Widget'),
    '#group' => 'group_favorites',
  );

  return $form;
}

Drupal: Debugging, Field Permissions, and Field Collections, Oh My!

I was just assigned a little bug in which a field is visible for users to add values to, but they can’t see the field to edit existing values. The following is a walkthrough of how I do a typical debug and the interesting results I found for this particular bug.

The first thing I did was try to reproduce the scenario. The field in question is in a Field Collection (the replacement for Drupal 6’s multigroup functionality) in the user’s profile. I verified that I could indeed add a value and save the user profile, but that the field was not visible when going back to that user profile’s edit screen. The next step was to make sure a value had even been correctly saved. I logged in as root and viewed the user’s profile edit page. Sure enough, the form held a field collection item with the correct value. I also verified this in a devel dump.

Ok, so the problem is that the field is not visible. The next step was to dump the value of $form in this particular form’s hook_form_FORM_ID_alter(). I saw that the #access attribute for this field was set to FALSE when the original viewer was looking at the form. Ok, so something was hiding the field. A quick grep across the codebase turned up no mention of the field name.

At this point, I was pretty sure it was something wonky with the Field Permissions contrib module that we’re using to provide more granular access to fields with less custom code. The first thing I did was to view the field’s config and verify that indeed it was set to custom permissions and that the type of user I tested with was correctly allowed access to edit existing values. Ok, so that wasn’t it; if it had to do with this module then it was something happening in the code itself. I opened up field_permissions.module and scrolled through till I found a likely starting point: hook_field_access().

Starting from that function, using logic and strategically placed dumps, I dug through the layers of functions until I reached _field_permissions_entity_is_owned_by_account(). The code in this function is a simple comparison: does the acted upon entity have a uid, and if so, does the acting user’s uid match the acted upon entity’s uid? If so, the function returns TRUE and the acting user has access to the field, and vice versa. I dpm()‘d both the $account and $entity and here’s where it got funny. Evidently entities of type FieldCollectionItem don’t have a uid property. This means the comparison was false, and the acting user was not granted access to edit the field.

Ok, simple enough. What’s the solution? To play nice with other modules, the Field Collection module should add a uid property to its entities, even if it’s redundant with the node/user entity that owns each FieldCollectionItem entity. As for my specific case, since this field is only displayed in the user’s profile edit form, and only that user and our staff roles have access to the edit form, it’s easiest to just set the #access property of that field in the $form structure back to TRUE, with a note summarizing why the hack is there.

Drupal: Get Node Term Count Grouped By Parent Term in a Hierarchal Vocabulary

hierarchal_taxonomy One of the sites my company manages reviews media products for teachers. The review content type has a term reference to describe which educational subjects the product addresses. It’s a two level hierarchal vocabulary, as you can see from the screenshot of the taxonomy admin page.

Recently the stakeholders for this content type asked my PM if we could add a new field to select the top level subject that was considered the primary area that the product addresses. Adding a field seemed like overkill so I researched my options. My first thought was to allow content editors to sort the terms per node so that the first result was the primary subject. There are several modules out there, like this one that do this. But this would add another step of work for them. Instead, I had the idea that wouldn’t it be most likely that the top level term that had the most child terms selected would be the primary subject? For example, if we have the top level terms of Science, English, Math and they have 3, 6, 5 child terms selected respectively, then English would be the primary subject. I ran this idea by my PM and he thought it was worth exploring.

What this meant was that I needed to generate a report of each node’s top level subject terms and how many child terms that subject had selected. Much easier to do this in SQL than in a view! This query returns the nid, node title, top level subject name, and count of child terms for that top level subject. The field name for the term reference is field_term_subjects, as you can see from the query.

SELECT 
  f.entity_id, n.title, td_parent.name, COUNT(td.tid) 
FROM 
  field_data_field_term_subjects f 
  JOIN taxonomy_term_data td ON td.tid = f.field_term_subjects_tid 
  JOIN taxonomy_term_hierarchy h ON h.tid = td.tid AND h.parent != 0 
  JOIN taxonomy_term_data td_parent ON td_parent.tid = h.parent 
  JOIN node n ON n.nid = f.entity_id 
GROUP BY 
  f.entity_id, h.parent;
absolut_links

Converting Relative Links to Absolute

I was recently given the task of adding a new API call to syndicate some articles from our site, articles that contain links to other content on our site. The question when writing site content is whether to make intra-site links absolute or not. If you do (e.g. http://foo.org/other-article) you’re tied to a specific domain name; if you use relative links (e.g. /other-article) they’ll break when you syndicate your content. My company chose the latter path anyway, so rather than strip all links from the text, I decided to make the article links absolute.

Note that this doesn’t handle <img> element src attributes. To do that, just find a regex that matches and repeat the code.

function absolutify($string) {

  $base_url = 'http://foo.org';

  preg_match_all('/<a.*?href\s*=\s*["\']([^"\']+)[^>]*>(.*?)<\/a>/si', $string, $hrefs);
  foreach ($hrefs[1] as $href) {

    // If the link is blank or absolute, nothing to do here
    if (!$href || substr($href, 0, 7) == 'http://') {
      continue;
    }

    // Create the absolute URL. We account for paths that start with a slash and ones that don't.
    $absolute_href = substr($href, 0, 1) == '/' ? $base_url . $href : $base_url . '/' . $href;

    // Replace the relative URL in the content with the absolute URL.
    // We use preg_replace instead of str_replace because it allows us to limit it to 1 result.
    // This is important so you don't get a link "/foo" followed by another link "/foo/bar".
    // The standard replace will replace both of them instead of the exact match. We also
    // wrap it in quotes so we don't get a problem with repeated URLs. For example: the first
    // /foo becomes http://www.foo.org/foo, then the second one finds the /foo in the already-absolutified
    // first instance and just replaces that instead of finding its own second occurrence.
    $string = preg_replace("|\"$href\"|", '"' . $absolute_href . '"', $string, 1);

  }

  return $string;
}

Nodequeues, subqueues, and conditional display

My company reviews and rates media such as mobile apps, video games, movies, etc in detail for parents and teachers to find appropriate content for their kids and students. We’re currently in the process of upgrading our site from Drupal 6 to 7, which includes a redesign and some new functionality. I was asked to upgrade the functionality for a small block of content that appears on each review node’s page titled Top Advice and Articles; this block contains links to other pieces of editorial content on our site.

The requirements were:

  • Allow up to 3 items to display in the block
  • Items that can be displayed must be of a certain node content type
  • Each item will display its image as a thumbnail and the item title, both linked to the item’s node page
  • Ideally, this would be done using nodequeues, which the editors are already familiar with and like the functionality thereof
  • Ideally, there would be a separate set of items for each of the types of content we review, i.e. they can tailor these based on whether it’s displaying in a movie review versus a website review, and so on

For the rest of this tutorial, I’m assuming you’re familiar with the Nodequeue module… Ok, so they wanted to use nodequeues, and based on their requirements it would need to be a separate nodequeue for each type of item we review. Nodequeues, as you may already know, are actually a two level hierarchy: the queue itself, which stores config information and one or more subqueues that use the parent queue’s config to store the actual nodes in the queue. Out of the box, Nodequeue only gives you the UI to create simple queues, i.e. queues that have one single subqueue. This gets the job done for most uses but in this case I didn’t want to clutter the UI with one simple queue per content type, so I decided to see if subqueues would do what I needed. Turns out, yes!

Creating a Subqueue

As I mentioned above, the UI doesn’t give you a way to do this visually, so it’s all done in your custom module, in this case a module named csm_review.

First, I defined the new type of queue I was creating.

/**
 * Implements hook_nodequeue_info().
 */
function csm_review_nodequeue_info() {
  return array('csm_review_block_top_advice' => array(
      'title' => t('Review - Top Advice and Articles'),
      'description' => t('Each entertainment product content type has its own unique subqueue. You can place nodes into any of these subqueues and they will show up on review pages for that content type.'),
    ));
}

Then, to make the code repeatable in our nightly upgrade builds, I wrote a custom function that I could run via drush to create the nodequeue and its children subqueues. The first query adds the parent queue and its config, and returns the new queue’s ID (autoincrement). The column definition is:

name
Machine name of the queue
title
Queue’s display name
size
Max items each subqueue can contain
owner
The name of the custom module implementing this queue. This becomes relevant later.
subqueue title
Not sure what this is used for but it’s a required column and all simple queues have an empty string stored

To meet the requirement of only allowing nodes of certain content types to be queued, I added some rows to the queue type filtering table. This is the equivalent of checking off all those content type boxes in the UI.

qid
The queue ID that I’m configuring, from the previous query
type
Machine name of the content type that is allowed to queued

Then I inserted one row into the subqueues table for each type of content. We have one central content type called csm_review that has the review metadata, which references one of seven different media content types that contains the actual products, so seven subqueues were created.

qid
The parent queue’s ID, from the previous query
reference
An arbitrary string that your new queue will use to differentiate between subqueues. In simple queues, the single subqueue’s reference is the queue ID. Because each subqueue was to be used for each type of product reviewed, I set the reference to the machine name of the content type of the reviewed product.

Here’s the final function, that I called via drush: drush php-eval "csm_review_build_top_advice_nodequeues()"

/**
 * Creates the top advice block queue and subqueues.
 */
function csm_review_build_top_advice_nodequeues() {

  // Create the primary nodequeue
  $qid = db_insert('nodequeue_queue')
    ->fields(array(
        'name'  => 'block_reviews_top_advice',
        'title' => 'Reviews Top Advice Block',
  	'size'  => 3,
        'owner' => 'csm_review',
        'subqueue_title' => '',
      ))
    ->execute();

  // Limit the types that can be selected
  $types = array('csm_blog', 'csm_ed_blog', 'csm_interactive_guide', 'csm_top_picks', 'csm_video',);
  foreach ($types as $type) {
    db_insert('nodequeue_types')
      ->fields(array(
          'qid'  => $qid,
          'type' => $type,
        ))
      ->execute();
  }

  // Create the ent prod subqueues
  $entertainment_products = array(
    'csm_app'     => 'App',
    'csm_book'    => 'Book',
    'csm_game'    => 'Game',
    'csm_movie'   => 'Movie',
    'csm_music'   => 'Music',
    'csm_tv'      => 'TV',
    'csm_website' => 'Website',
  );
  foreach ($entertainment_products as $type => $name) {
    db_insert('nodequeue_subqueue')
      ->fields(array(
          'qid'       => $qid,
          'reference' => $type,
          'title'     => "Top Advice and Articles Block: $name Reviews",
	))
      ->execute();
  }
}

After running my function, this is what my new queue and subqueues looked like:
Queue Parent
Subqueues

That’s great, but there’s one last step to get the subqueues visible in the Nodequeue tab that shows for each node if you have permissions to add nodes to queues. Because Nodequeue only knows how to manage simple queues, we have to tell it how to retrieve the subqueues that belong to our new custom queue. It took a while to find out how to do this, because this is technically not a hook, although it acts like one. Nodequeue looks for a function named $queue->owner . '_nodequeue_subqueues', so for consistency with Drupal’s hook system, that’s why I set the owner column of my custom queue to the module I coded this in. This function expects a returned string or array of the references of all subqueues belonging to this custom queue. Remember that reference column we set earlier? This is where it starts coming into play, and even more later.

/**
 * Implements hook_nodequeue_subqueues().
 */
function csm_review_nodequeue_subqueues(&$queue, $node) {
  // We're only at this point if the node is of a type that can belong to the top advice queue
  // so just return the references for all the subqueues in the top advice queue
  return db_query("SELECT reference FROM {nodequeue_subqueue} WHERE qid = :qid", array(':qid' => $queue->qid))->fetchCol();
}

And here’s what you’ll see when you click on the Nodequeue tab for a node
Queue selection for node.

Conditional Display of Subqueues

Well, great, we’re done, right? Nope. We still need to not only display our queues in the node page but we also have to only show the subqueue that matches the media type of the review (e.g. csm_tv for TV show reviews). Views to the rescue! We happen to be using Panels so I created this View as a content pane, but you can create it as a block. The two configurations necessary for this to work are Relationships and Contextual Filters.
view_config

Add a Relationship of type Nodequeue: queue to show items that are in a queue
relationship_selector

Select your newly created queue to show only items that are in this queue
relationships

Then, we want to tell the View which of the subqueues to use. That will change based on the context the queue is displayed in so we’ll be passing that value through as a Contextual Filter. Add a new Nodequeue: subqueue reference filter
filter_selector

From here on out, I’ll assume you know how to embed a View in a way that allows you to pass in contextual filters, as it’s different based on whatever layout engine you use (Panels vs Display Suite, etc). In my case, I had the context of the content type of the product node that was referenced by the review node, the panel pane in which my View content pane was embedded. This would also work for a block in Panels. YMMV otherwise. But that’s pretty much it!

Emacs: converting existing tabs to spaces

So you already know to use spaces instead of tabs for indenting. But what about those files that already have them? Here’s how to untabify an entire file at once. Note that you’ll still have to align anything that is out of whack because of the old tabs, but at least they’ll be spaces now.

  1. Go to the start of the file: M-<
  2. Start buffer selection: C-x h
  3. Mark the entire buffer: M-x mark-whole-buffer
  4. Convert tabs to spaces in the selected region: M-x untabify

You can do a partial region with this command too, just select a smaller region instead of the whole file.

Don’t Be That Guy

So we interviewed someone today for a developer position. I gave him a simple weeding out question, one that I explicitly told him was just for that purpose. The question was: given an integer greater than zero, write a function to determine if it’s a power of 2. I also told him I didn’t care about language/syntax, that he could use pseudocode. First of all, this guy hemmed and hawed and without even trying, said that he was tired, hadn’t gotten a lot of sleep, and gave up saying he didn’t know binary math. We prodded at him. Finally he made an attempt after I said “well, why don’t you take an example like 64 and see how to make it work?” He eventually came up with a mediocre but functional answer using a while loop and a break. As a followup, I asked him to do it with a recursive function. He couldn’t make it work, saying it was “tricky”; he just kept writing more and more complex code.

But he seemed to have a good attitude and was willing to learn, etc so while I wasn’t impressed, I was willing to attribute it to nerves and see how he performed in the more technical part of the interview. He did poorly there and that was that. But here’s the kicker… His last interview was with two of our product managers. He evidently told them that questions like the one I asked him don’t accurately represent a candidate’s skills, and why would he ever need to find out if a number is a power of 2. Are you kidding? Really? Who the hell 1) doesn’t understand the purpose of basic algorithm questions 2) tells someone else in the interview process that you think the question is bad?

BTW, the power of 2 question is one that I made myself solve the first time I heard it without reading an answer to see if it’s a fair question to ask. So yes, I do know how simple it is to solve; it took me about 30 seconds to get the approach and another minute or two to prettify for consumption. Just one recursive sample is below.

function isPowerOfTwo($number) {
  
  // If the number is odd, it's not a power of two, we can short-circuit
  if ($number % 2) {
    return FALSE;
  }

  if ($number > 2) {
    return isPowerOfTwo($number/2);
  }
  return ! (bool) ($number % 2);
}