Alter Views sort by taxonomy weight

Submitted by christophe on Mon, 03/10/2016 - 19:10

The use case is that we want to sort a list of users by job title, where job title is a term reference to a dedicated vocabulary.
The sort is done by the job title term weight (defined via the vocabulary list).

I choosed to apply a custom sort function on a view, instead of a custom dynamic / entity query for two reasons :

  1. the client have access to Views so he can continue to apply changes via the UI (format, fields, filters, ...)
  2. the query involves third party database (CiviCRM) that is already well handled by the CiviCRM Entity module so we can avoid custom API call to CiviCRM.
/**
 * Implements hook_views_pre_render().
 *
 * Applies custom sort by job title weight on a view.
 *
 * @param $view
 */
function my_module_views_pre_render(&$view) {
  if($view->name == 'my_view') {
    // load vocabulary
    $job_title_vocab = taxonomy_vocabulary_machine_name_load('job_title');
    $job_titles = taxonomy_get_tree($job_title_vocab->vid);
    // index for fast weight retrieval, avoids nested foreach
    $job_title_weight = array();
    foreach ($job_titles as $job_title) {
      $job_title_weight[$job_title->tid] = $job_title->weight;
    }
    foreach ($view->result as $user) {
      // assume we fetch the first one if multiple
      $user_job_title = $user->field_field_job_title[0]['raw']['tid'];
      // append my_module_job_title_weight property to sort on, shorthand
      $user->my_module_job_title_weight = $job_title_weight[$user_job_title];
    }
    usort($view->result, '_my_module_job_title_weight_compare');
  }
}

/**
 * Comparable functor to be used by usort.
 *
 * @param $a
 * @param $b
 *
 * @return int
 */
function _my_module_job_title_weight_compare($a, $b) {
  if ($a->my_module_job_title_weight == $b->my_module_job_title_weight) {
    return 0;
  }
  return ($a->my_module_job_title_weight < $b->my_module_job_title_weight) ? -1 : 1;
}

 

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.