- Published on
Alter Views sort by taxonomy weight
- Authors
- Name
- Christophe Jossart
- @colorfield
The use case is 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 :
- the client have access to Views so he can continue to apply changes via the UI (format, fields, filters, ...)
- 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;
}