taxonomy_tools.module in Taxonomy Tools 8
Same filename and directory in other branches
Drupal hooks and functions to work with taxonomy terms.
User is provided with a taxonomy term overview table that implements functionality from all Taxonomy Tools submodules.
File
taxonomy_tools.moduleView source
<?php
/**
* @file
* Drupal hooks and functions to work with taxonomy terms.
*
* User is provided with a taxonomy term overview table that
* implements functionality from all Taxonomy Tools submodules.
*/
/**
* Implements hook_menu().
*/
function taxonomy_tools_menu() {
$items = array();
$items['admin/config/taxonomy-tools'] = array(
'title' => 'Taxonomy Tools',
'description' => 'Taxonomy Tools configuration',
'page callback' => 'system_admin_menu_block_page',
'access arguments' => array(
'access administration pages',
),
'file' => 'system.admin.inc',
'file path' => drupal_get_path('module', 'system'),
);
$items['admin/structure/taxonomy/%taxonomy_vocabulary_machine_name/overview'] = array(
'title' => 'Overview',
'description' => 'Vocabulary overview table',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'taxonomy_tools_overview',
3,
5,
),
'file' => 'taxonomy_tools.admin.inc',
'file path' => drupal_get_path('module', 'taxonomy_tools'),
'type' => MENU_LOCAL_TASK,
'weight' => 50,
'access callback' => 'taxonomy_tools_overview_access',
'access arguments' => array(
3,
),
);
$items['admin/structure/taxonomy/%taxonomy_vocabulary_machine_name/overview/%/add'] = array(
'title' => 'Add term',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'taxonomy_form_term',
array(),
3,
),
'file path' => drupal_get_path('module', 'taxonomy'),
'file' => 'taxonomy.admin.inc',
'access callback' => 'taxonomy_tools_overview_access',
'access arguments' => array(
3,
TRUE,
),
);
$items['admin/structure/taxonomy/%taxonomy_vocabulary_machine_name/overview/add'] = array(
'title' => 'Add term',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'taxonomy_form_term',
array(),
3,
),
'file path' => drupal_get_path('module', 'taxonomy'),
'file' => 'taxonomy.admin.inc',
'access callback' => 'taxonomy_tools_overview_access',
'access arguments' => array(
3,
TRUE,
),
);
$items['taxonomy/term/%taxonomy_term/overview'] = array(
'title' => 'Subtree',
'description' => 'Subtree overview table',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'taxonomy_tools_overview',
NULL,
2,
),
'file' => 'taxonomy_tools.admin.inc',
'file path' => drupal_get_path('module', 'taxonomy_tools'),
'access arguments' => array(
'use taxonomy tools',
),
'weight' => 50,
'type' => MENU_LOCAL_TASK,
);
$items['taxonomy/term/%taxonomy_term/overview/add/%taxonomy_vocabulary_machine_name'] = array(
'title' => 'Add term',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'taxonomy_form_term',
array(),
5,
),
'file path' => drupal_get_path('module', 'taxonomy'),
'file' => 'taxonomy.admin.inc',
'access callback' => 'taxonomy_tools_overview_access',
'access arguments' => array(
5,
TRUE,
),
);
return $items;
}
/**
* Implements hook_theme().
*/
function taxonomy_tools_theme() {
return array(
'taxonomy_tools_overview' => array(
'render element' => 'form',
),
);
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function taxonomy_tools_form_taxonomy_form_term_alter(&$form, &$form_state) {
// Preset default parent term.
if (arg(4) && arg(4) == 'overview' && is_numeric(arg(5))) {
$form['relations']['parent']['#default_value'] = array(
arg(5) => arg(5),
);
}
if (arg(3) && arg(3) == 'overview' && is_numeric(arg(2))) {
$form['relations']['parent']['#default_value'] = array(
arg(2) => arg(2),
);
}
}
/**
* Implements hook_menu_alter().
*/
function taxonomy_tools_menu_alter(&$items) {
$use_view = FALSE;
if (module_exists('views')) {
$views = views_get_enabled_views();
foreach ($views as $view) {
foreach ($view->display as $display) {
if (isset($display->display_options['path']) && $display->display_options['path'] == 'taxonomy/term/%') {
// If term page path is used by a view.
$items['taxonomy/term/%views_arg']['access callback'] = 'taxonomy_tools_taxonomy_term_access';
$items['taxonomy/term/%views_arg']['access arguments'] = array(
2,
);
$use_view = TRUE;
break 2;
}
}
}
}
if (!$use_view) {
$items['taxonomy/term/%taxonomy_term']['access callback'] = 'taxonomy_tools_taxonomy_term_access';
$items['taxonomy/term/%taxonomy_term']['access arguments'] = array(
2,
);
}
}
/**
* Controls the access to the taxonomy term.
*
* If the taxonomy term is from a vocabulary that uses Taxonoomy Publisher
* functionality, it's status will checked to determine whether the user is
* allowed to access it.
*
* @param stdClass $term
* A taxonomy term object or a string containing taxonomy term ID.
*
* @return bool
* TRUE if user is allowed to access the taxonomy term, and FALSE if isn't.
*/
function taxonomy_tools_taxonomy_term_access($term) {
$access = user_access('access content');
// In case only term ID is passed as parameter we must load the term object.
if (is_numeric($term)) {
$term = taxonomy_term_load($term);
}
if (is_object($term)) {
if (module_exists('taxonomy_tools_publisher') && $access) {
// If Taxonomy Publisher is enabled and term is available to the user.
$config = array_filter(variable_get('taxonomy_tools_publisher_config', array()));
if (!empty($config) && in_array($term->vocabulary_machine_name, $config)) {
// We must check the whole hierarchy branch up to the top level.
$result = taxonomy_tools_publisher_check_branch($term->tid);
if (!user_access('bypass taxonomy publisher') && $result == 0) {
// User isn't allowed to access the term,
// because the term (or it's parent term) is not published
// and user doesn't have permission to view unpublished terms.
$access = FALSE;
}
}
}
if (module_exists('taxonomy_tools_role_access') && $access && !user_access('bypass taxonomy role access')) {
// If Taxonomy Role Access is enabled and term is still available to
// the user and user doesn't have permissions to bypass settings.
$access = FALSE;
global $user;
$roles = $user->roles;
$config = variable_get('taxonomy_tools_role_access_role_config', array());
foreach ($roles as $rid => $role) {
if (in_array($rid, $config)) {
// User role is controlled by Taxonomy Role Access.
$role_access = taxonomy_tools_role_access_get_access($term->tid, $rid);
if ($role_access) {
// Term is available to the user role.
$access = TRUE;
break;
}
}
else {
// One of the user roles is not controlled by Taxonomy Role Access
// term is available to the user.
$access = TRUE;
break;
}
}
}
}
else {
// Something is wrong with the passed parameter - deny access.
$access = FALSE;
}
return $access;
}
/**
* Implements hook_node_grants().
*/
function taxonomy_tools_node_grants($account, $op) {
$node_grants = array();
$roles = $account->roles;
$node_grants = array(
'taxonomy_tools' => array_keys($roles),
);
return $node_grants;
}
/**
* Implements hook_node_access_records().
*/
function taxonomy_tools_node_access_records($node) {
$grants = array();
$grants = taxonomy_tools_build_grants($node);
return $grants;
}
/**
* Builds node access grants for all user roles.
*
* @param stdClass $node
* A node object.
*
* @return array
* An array containing node access grants.
*/
function taxonomy_tools_build_grants($node) {
$grants = array();
// Get all terms associated with this node.
$query = db_select('taxonomy_index', 'foo');
$query
->addField('foo', 'tid');
$query
->condition('foo.nid', $node->nid);
$query
->join('taxonomy_term_data', 'bar', 'foo.tid = bar.tid');
$query
->addField('bar', 'vid');
$query
->join('taxonomy_vocabulary', 'baz', 'bar.vid = baz.vid');
$query
->addField('baz', 'machine_name');
$result = $query
->execute()
->fetchAll();
// Get all user roles.
$roles = user_roles();
$roles = array_keys($roles);
// Create node access grants for each user role.
foreach ($roles as $rid) {
$view = TRUE;
if (!empty($result)) {
// There are terms associated with this node.
$permissions = taxonomy_tools_role_permissions_all($rid);
if (module_exists('taxonomy_tools_publisher') && $view) {
// If Taxonomy Publisher is enabled and node is visible to user role.
$view = FALSE;
$config = array_filter(variable_get('taxonomy_tools_publisher_config', array()));
foreach ($result as $term_data) {
if (!in_array($term_data->machine_name, $config) || in_array($term_data->machine_name, $config) && taxonomy_tools_publisher_check_branch($term_data->tid)) {
// One of terms is not controlled by Taxonomy Publisher
// or is controlled but is seen by user.
$view = TRUE;
break;
}
}
if (!$view && in_array('bypass taxonomy publisher', $permissions)) {
// None of associated terms is available to the user,
// but user is allowed to see nodes from unpublished terms.
$view = TRUE;
}
}
if (module_exists('taxonomy_tools_role_access') && $view) {
// If Taxonomy Role Access is enabled and node is visible to user role.
$v_config = array_filter(variable_get('taxonomy_tools_role_access_vocab_config', array()));
$r_config = variable_get('taxonomy_tools_role_access_role_config', array());
if (in_array($rid, $r_config)) {
$view = FALSE;
// Only if user role is controlled by Taxonomy Role Access.
foreach ($result as $term_data) {
if (!in_array($term_data->machine_name, $v_config) || in_array($term_data->machine_name, $v_config) && taxonomy_tools_role_access_get_access($term_data->tid, $rid)) {
// One of terms is not controlled by Taxonomy Role Access
// or is controlled but is available to this user role.
$view = TRUE;
break;
}
}
if (!$view && in_array('bypass taxonomy role access', $permissions)) {
// None of associated terms is available to the user,
// but user is allowed to see nodes from restricted terms.
$view = TRUE;
}
}
}
}
$grants[] = array(
'realm' => 'taxonomy_tools',
'gid' => $rid,
'grant_view' => $view ? 1 : 0,
'grant_update' => 0,
'grant_delete' => 0,
'priority' => 0,
);
}
return $grants;
}
/**
* Collects all permissions (also inherited) specific to a user role.
*
* @param string $rid
* A string containing user role ID.
*
* @return array
* An array of user permissions.
*/
function taxonomy_tools_role_permissions_all($rid) {
$user_roles = array();
$user_roles[$rid] = $rid;
if ($rid != 1) {
// All other roles than anonymous user inherit permissions from
// authenticated user.
$user_roles[2] = 2;
}
$permissions = user_role_permissions($user_roles);
$permissions_all = array();
// Merge all permissions.
foreach ($permissions as $data) {
$permissions_all = array_merge($permissions_all, array_keys($data));
}
// Remove duplicate values.
$permissions_all = array_unique($permissions_all);
return $permissions_all;
}
/**
* Fetches ID's of all nodes associated with specific taxonomy term.
*
* @param string $tid
* A string containing taxonomy term ID.
*
* @return array
* An array containing all associated node ID's.
*/
function taxonomy_tools_associated_nodes($tid) {
$nids = array();
// Get all associated node ID's.
$query = db_select('taxonomy_index', 'foo');
$query
->addField('foo', 'nid');
$query
->condition('foo.tid', $tid);
$query
->execute();
$result = $query
->execute()
->fetchAll();
foreach ($result as $data) {
$nids[] = $data->nid;
}
// Check if this term has any children.
$query = db_select('taxonomy_term_hierarchy', 'foo');
$query
->addField('foo', 'tid');
$query
->condition('foo.parent', $tid);
$result = $query
->execute()
->fetchAll();
foreach ($result as $data) {
// Nodes associated with children terms could also be affected;
// fetch those nids also.
$nids = array_merge($nids, taxonomy_tools_associated_nodes($data->tid));
}
return $nids;
}
/**
* Builds new access grants for nodes associated with specific taxonomy term.
*
* @param stdClass $term
* A taxonomy term object
*/
function taxonomy_tools_rebuild_access_grants($term) {
if (is_numeric($term)) {
$term = taxonomy_term_load($term);
}
$rebuild = FALSE;
if (module_exists('taxonomy_tools_publisher') && !$rebuild) {
// Whether Taxonomy Publisher module is enabled.
$config = array_filter(variable_get('taxonomy_tools_publisher_config', array()));
// Only if the vocabulary uses Taxonomy Publisher.
if (!empty($config) && in_array($term->vocabulary_machine_name, $config)) {
$rebuild = TRUE;
}
}
if (module_exists('taxonomy_tools_role_access') && !$rebuild) {
// Whether Taxonomy Role Access module is enabled.
$config = array_filter(variable_get('taxonomy_tools_role_access_vocab_config', array()));
// Only if the vocabulary uses Taxonomy Role Access.
if (!empty($config) && in_array($term->vocabulary_machine_name, $config)) {
$rebuild = TRUE;
}
}
if ($rebuild) {
// Get all associated nodes.
$nids = taxonomy_tools_associated_nodes($term->tid);
foreach ($nids as $nid) {
// Rewrite node access grants.
$node = node_load($nid);
node_access_acquire_grants($node);
// Allow other modules to act on node access grants rebuild.
module_invoke_all('taxonomy_tools_node_access_grants_rebuild', $node);
}
}
}
/**
* Implements hook_taxonomy_term_update().
*/
function taxonomy_tools_taxonomy_term_update($term) {
taxonomy_tools_rebuild_access_grants($term);
}
/**
* Implements hook_taxonomy_term_delete().
*/
function taxonomy_tools_taxonomy_term_delete($term) {
taxonomy_tools_rebuild_access_grants($term);
}
/**
* Returns full parent hierarchy of taxonomy term.
*
* @param string $tid
* Taxonomy term identificator.
*
* @return array
* An array representing full hierarchy of taxonomy term.
*/
function taxonomy_tools_term_path($tid, $return = TRUE) {
$path = array();
$query = db_select('taxonomy_term_data', 'foo');
$query
->addField('foo', 'name');
$query
->condition('foo.tid', $tid);
$query
->leftJoin('taxonomy_term_hierarchy', 'bar', 'foo.tid = bar.tid');
$query
->addField('bar', 'parent');
$result = $query
->execute()
->fetchObject();
if ($return) {
$path[] = array(
'tid' => $tid,
'name' => $result->name,
);
}
if ($result->parent > 0) {
$path = array_merge($path, taxonomy_tools_term_path($result->parent));
}
return $path;
}
/**
* Implements hook_permission().
*/
function taxonomy_tools_permission() {
return array(
'use taxonomy tools' => array(
'title' => t('Use Taxonomy Tools'),
'description' => t('Allows the user to access Taxonomy Tools overview page.'),
),
);
}
/**
* Controls access to Taxonomy Tools overview page.
*
* @return bool
* TRUE if the vocabulary uses at least one of Taxonomy Tools
* sub-modules and user has permission to access
* Taxonomy Tools overview page;
* FALSE otherwise.
*/
function taxonomy_tools_overview_access($vocabulary, $add = NULL) {
$access = FALSE;
$access = user_access('use taxonomy tools');
if ($access && $add && !(user_access('administer taxonomy') || user_access('edit terms in ' . $vocabulary->vid))) {
$access = FALSE;
}
return $access;
}
/**
* Implements hook_admin_paths().
*/
function taxonomy_tools_admin_paths() {
$paths = array(
'taxonomy-tools/*/order/*' => TRUE,
);
return $paths;
}
/**
* Implements hook_taxonomy_term_presave().
*/
function taxonomy_tools_taxonomy_term_presave($term) {
if (arg(4) == 'overview' || arg(3) == 'overview') {
$count = array();
// Take in account that term can have more than one parent.
foreach ($term->parent as $tid) {
$query = db_select('taxonomy_term_hierarchy', 'foo');
$query
->addField('foo', 'tid');
$query
->condition('foo.parent', $tid);
$query
->join('taxonomy_term_data', 'bar', 'foo.tid = bar.tid');
$query
->condition('bar.vid', $term->vid);
$count[] = $query
->countQuery()
->execute()
->fetchField();
}
// Set term weight to siblings count + 1.
// We use the biggest siblings count.
$term->weight = max($count) + 1;
}
}
/**
* Implements hook_preprocess_HOOK().
*/
function taxonomy_tools_preprocess_page(&$variables) {
if (arg(4) == 'overview' && arg(5) != 'add' && arg(6) != 'add') {
// Proper breadcrumb for vocabulary overview page.
$breadcrumb = array();
$options = array(
'html' => TRUE,
);
$step = l(t('Home'), '<front>', $options);
array_push($breadcrumb, $step);
$step = l(t('Administration'), 'admin', $options);
array_push($breadcrumb, $step);
$step = l(t('Structure'), 'admin/structure', $options);
array_push($breadcrumb, $step);
$step = l(t('Taxonomy'), 'admin/structure/taxonomy', $options);
array_push($breadcrumb, $step);
if (is_numeric(arg(5))) {
$query = db_select('taxonomy_vocabulary', 'foo');
$query
->addField('foo', 'name');
$query
->condition('foo.machine_name', arg(3));
$vocabulary_name = $query
->execute()
->fetchField();
$step = l($vocabulary_name, 'admin/structure/taxonomy/' . arg(3) . '/overview', $options);
array_push($breadcrumb, $step);
$path = array_reverse(taxonomy_tools_term_path(arg(5), FALSE));
if (!empty($path)) {
foreach ($path as $term) {
$step = l($term['name'], 'admin/structure/taxonomy/' . arg(3) . '/overview/' . $term['tid'], $options);
array_push($breadcrumb, $step);
}
}
}
drupal_set_breadcrumb($breadcrumb);
}
if (arg(4) == 'overview' && (arg(5) == 'add' || arg(6) == 'add')) {
// Proper breadcrumb when adding new term through vocabulary
// overview page.
$breadcrumb = array();
$options = array(
'html' => TRUE,
);
$step = l(t('Home'), '<front>', $options);
array_push($breadcrumb, $step);
$step = l(t('Administration'), 'admin', $options);
array_push($breadcrumb, $step);
$step = l(t('Structure'), 'admin/structure', $options);
array_push($breadcrumb, $step);
$step = l(t('Taxonomy'), 'admin/structure/taxonomy', $options);
array_push($breadcrumb, $step);
$query = db_select('taxonomy_vocabulary', 'foo');
$query
->addField('foo', 'name');
$query
->condition('foo.machine_name', arg(3));
$vocabulary_name = $query
->execute()
->fetchField();
$step = l($vocabulary_name, 'admin/structure/taxonomy/' . arg(3) . '/overview', $options);
array_push($breadcrumb, $step);
if (is_numeric(arg(5))) {
$path = array_reverse(taxonomy_tools_term_path(arg(5)));
if (!empty($path)) {
foreach ($path as $term) {
$step = l($term['name'], 'admin/structure/taxonomy/' . arg(3) . '/overview/' . $term['tid'], $options);
array_push($breadcrumb, $step);
}
}
}
drupal_set_breadcrumb($breadcrumb);
}
if (arg(3) == 'overview' && arg(4) == 'add' && is_numeric(arg(2))) {
// Proper breadcrumb when adding new term through vocabulary
// overview page which is opened through term page.
$breadcrumb = array();
$options = array(
'html' => TRUE,
);
$step = l(t('Home'), '<front>', $options);
array_push($breadcrumb, $step);
$path = array_reverse(taxonomy_tools_term_path(arg(2)));
if (!empty($path)) {
foreach ($path as $term) {
$step = l($term['name'], 'taxonomy/term/' . $term['tid'] . '/overview', $options);
array_push($breadcrumb, $step);
}
}
drupal_set_breadcrumb($breadcrumb);
}
}
/**
* Returns the title of a taxonomy term.
*
* @param string $tid
* The taxonomy term title.
*/
function taxonomy_tools_term_title($tid) {
$title = '';
$query = db_select('taxonomy_term_data', 'foo');
$query
->addField('foo', 'name');
$query
->condition('foo.tid', $tid);
$title = $query
->execute()
->fetchField();
return $title;
}
/**
* Implements hook_module_implements_alter().
*/
function taxonomy_tools_module_implements_alter(&$implementations, $hook) {
if ($hook == 'menu_alter' && module_exists('views')) {
// Implementation of hook_menu_alter() of this module is called last.
$group = $implementations['taxonomy_tools'];
unset($implementations['taxonomy_tools']);
$implementations['taxonomy_tools'] = $group;
}
}
Functions
Name![]() |
Description |
---|---|
taxonomy_tools_admin_paths | Implements hook_admin_paths(). |
taxonomy_tools_associated_nodes | Fetches ID's of all nodes associated with specific taxonomy term. |
taxonomy_tools_build_grants | Builds node access grants for all user roles. |
taxonomy_tools_form_taxonomy_form_term_alter | Implements hook_form_FORM_ID_alter(). |
taxonomy_tools_menu | Implements hook_menu(). |
taxonomy_tools_menu_alter | Implements hook_menu_alter(). |
taxonomy_tools_module_implements_alter | Implements hook_module_implements_alter(). |
taxonomy_tools_node_access_records | Implements hook_node_access_records(). |
taxonomy_tools_node_grants | Implements hook_node_grants(). |
taxonomy_tools_overview_access | Controls access to Taxonomy Tools overview page. |
taxonomy_tools_permission | Implements hook_permission(). |
taxonomy_tools_preprocess_page | Implements hook_preprocess_HOOK(). |
taxonomy_tools_rebuild_access_grants | Builds new access grants for nodes associated with specific taxonomy term. |
taxonomy_tools_role_permissions_all | Collects all permissions (also inherited) specific to a user role. |
taxonomy_tools_taxonomy_term_access | Controls the access to the taxonomy term. |
taxonomy_tools_taxonomy_term_delete | Implements hook_taxonomy_term_delete(). |
taxonomy_tools_taxonomy_term_presave | Implements hook_taxonomy_term_presave(). |
taxonomy_tools_taxonomy_term_update | Implements hook_taxonomy_term_update(). |
taxonomy_tools_term_path | Returns full parent hierarchy of taxonomy term. |
taxonomy_tools_term_title | Returns the title of a taxonomy term. |
taxonomy_tools_theme | Implements hook_theme(). |