View source
<?php
define('FILTERED_HTML', 1);
function taxonomy_redirect_help($section) {
switch ($section) {
case 'admin/build/taxonomy_redirect':
return t('On this form you may tell Drupal where taxonomy terms should link to. By default, modules handled by the taxonomy modules link to <strong>taxonomy/term/!tid</strong>; however, there are many instances where a user may want to override this behavior and provide custom content. You can create redirections for all terms of a vocabulary or you can create them for individual terms. Indiviual term redirects take precedence over whole vocabulary redirects. Variables available for the path are <strong>!tid</strong> (term id), <strong>!name</strong> (term name), <strong>!parent_ids</strong> (a path of parent term ids eg/ great_grandparent/grandparent/parent) and <strong>!parent_names</strong> (a path of parent terms by name). If you are using PHP to create your path you will have the following variables available: <strong>$tid</strong> (term id), <strong>$tname</strong> (term name) and <strong>$nid</strong> (node id).');
}
}
function taxonomy_redirect_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'admin/build/taxonomy_redirect',
'title' => t('Taxonomy redirect'),
'description' => t('Override the default url paths for taxonomy terms.'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'taxonomy_redirect_redirects_form',
),
'access' => user_access('administer taxonomy'),
'type' => MENU_NORMAL_ITEM,
);
$items[] = array(
'path' => 'admin/build/taxonomy_redirect/redirects',
'title' => 'Redirects',
'weight' => -10,
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items[] = array(
'path' => 'admin/build/taxonomy_redirect/settings',
'title' => 'Settings',
'callback' => 'drupal_get_form',
'callback arguments' => array(
'taxonomy_redirect_settings_form',
),
'access' => user_access('administer taxonomy'),
'weight' => 0,
'type' => MENU_LOCAL_TASK,
);
}
return $items;
}
function taxonomy_redirect_settings_form() {
$form = array();
$form['taxonomy_redirect_term_level_redirects'] = array(
'#type' => 'checkbox',
'#title' => t('Enable term level redirects'),
'#default_value' => variable_get('taxonomy_redirect_term_level_redirects', TRUE),
'#description' => t('If checked, redirects per term will be possible, otherwise you can only have redirects per vocabulary'),
);
return system_settings_form($form);
}
function taxonomy_redirect_redirects_form() {
drupal_add_js(drupal_get_path('module', 'taxonomy_redirect') . '/taxonomy_redirect.js');
$form = array();
$result = db_query("SELECT * FROM {taxonomy_redirect}");
$redirects = array();
while ($data = db_fetch_object($result)) {
$redirects[] = $data;
}
$form['redirects']['#tree'] = TRUE;
foreach ($redirects as $i => $redirect) {
$form['redirects'][$i]['#tree'] = TRUE;
$vocab = taxonomy_get_vocabulary($redirect->vid);
$form['redirects'][$i]['vocabulary'] = array(
'#type' => 'markup',
'#value' => $vocab->name,
);
$form['redirects'][$i]['vid'] = array(
'#type' => 'hidden',
'#value' => $redirect->vid,
);
if ($redirect->tid && $redirect->tid > 0) {
$term = taxonomy_get_term($redirect->tid);
$term_name = $term->name;
}
else {
$term_name = '';
}
$form['redirects'][$i]['term'] = array(
'#type' => 'markup',
'#value' => $term_name,
);
$form['redirects'][$i]['tid'] = array(
'#type' => 'hidden',
'#value' => $redirect->tid,
);
$form['redirects'][$i]['path'] = array(
'#type' => 'markup',
);
$phpcode = taxonomy_redirect_get_php_filter();
if ($redirect->filter == $phpcode) {
$form['redirects'][$i]['path']['#value'] = 'PHP Code';
}
else {
$form['redirects'][$i]['path']['#value'] = $redirect->path;
}
$text_array = array_filter(preg_split("/\n|\r/", $redirect->remove_text), 'taxonomy_redirect_filter_empty_lines');
$remove_text = '';
foreach ($text_array as $text) {
$remove_text .= $remove_text ? ", '" . $text . "'" : "'" . $text . "'";
}
$form['redirects'][$i]['remove_text'] = array(
'#type' => 'markup',
'#value' => $remove_text,
);
$form['redirects'][$i]['separator'] = array(
'#type' => 'markup',
'#value' => $redirect->separator_replace,
);
$form['redirects'][$i]['path_case'] = array(
'#type' => 'markup',
'#value' => $redirect->path_case,
);
$onclick = '$(\'#edit-add-redirect-vocab-select\').val(' . $redirect->vid . ');
vocab($(\'#edit-add-redirect-vocab-select\').val());
$(\'#edit-path\').val(decodeURIComponent( \'' . rawurlencode($redirect->path) . '\'));
$(\'#edit-path-case\').val(\'' . $redirect->path_case . '\');
$(\'#edit-filter\').val(\'' . $redirect->filter . '\');
$(\'#edit-separator-replace\').val(decodeURIComponent( \'' . rawurlencode($redirect->separator_replace) . '\'));
$(\'#edit-remove-text\').val(decodeURIComponent( \'' . rawurlencode($redirect->remove_text) . '\'));
return false;';
$form['redirects'][$i]['load'] = array(
'#type' => 'markup',
'#value' => l('load into editor', '', array(
'onclick' => $onclick,
)),
);
$form['redirects'][$i]['delete'] = array(
'#type' => 'checkbox',
'#return_value' => 1,
'#default_value' => 0,
);
}
$form['delete_message'] = array(
'#type' => 'item',
'#value' => t("Redirects checked 'delete' will be deleted on submit."),
'#prefix' => '<span style="color:red;font-weight:bold">',
'#suffix' => '</span>',
);
$vocabs = taxonomy_get_vocabularies();
$vocab_options[0] = "- None selected -";
foreach ($vocabs as $vocab) {
$vocab_options[$vocab->vid] = $vocab->name;
if (variable_get('taxonomy_redirect_term_level_redirects', TRUE)) {
$vid = $vocab->vid;
$term_select = taxonomy_form($vid);
$term_select['#attributes'] = array(
'style' => 'display:none',
'onchange' => 'term(this.value);return false',
);
$term_select['#title'] = "";
$term_select['#id'] = "term_select_{$vid}";
$term_select['#multiple'] = TRUE;
$form["term_select_{$vid}"] = $term_select;
}
}
$form['add_redirect'] = array(
'#type' => 'fieldset',
'#title' => t('Add new redirect'),
'#tree' => TRUE,
'#id' => 'div_addnew',
);
$form['add_redirect']['vocab_select'] = array(
'#type' => 'select',
'#options' => $vocab_options,
'#title' => 'Select vocabulary',
'#name' => 'vocab_select',
);
if (variable_get('taxonomy_redirect_term_level_redirects', TRUE)) {
$form['add_redirect']['vocab_select']['#attributes'] = array(
'onchange' => 'vocab(this.value);//return false',
);
$form['add_redirect']['vocab_select']['#suffix'] = '<div id="div_termselect"></div>';
$form['term_id'] = array(
'#type' => 'hidden',
'#value' => 0,
'#id' => 'term_id',
);
}
$form['add_redirect']['filter'] = array(
'#id' => 'edit-filter',
'#type' => 'select',
'#title' => t('Filter'),
'#options' => _taxonomy_redirect_get_filters(),
'#description' => t('Select an input format for the term path. If using PHP use opening and closing brackets'),
);
$form['add_redirect']['path'] = array(
'#id' => 'edit-path',
'#type' => 'textarea',
'#title' => t('Enter path'),
'#description' => t('Do not place a leading or trailing /. Available variables: !tid, !name, !parent_ids, !parent_names. You can also enter PHP code (use enclosing PHP tags) to create the path if PHP Code is selected in the filter option above. Just make your PHP code return the desired path. Variables available to your PHP code are $tid, $tname and $nid. Define the function taxonomy_redirect_custom_term_path($term, $path, $separator, $remove_text) to customise further.'),
'#cols' => 60,
'#rows' => 5,
);
$form['add_redirect']['remove_text'] = array(
'#id' => 'edit-remove-text',
'#type' => 'textarea',
'#title' => t('Remove text'),
'#description' => t('A list of text to be removed from the url. Put each piece of text to be removed on a new line. Text can be one or more characters. This may be useful to remove punctuation. This removal will be done before separators are replaced. (case sensitive)'),
'#rows' => 4,
);
$form['add_redirect']['separator_replace'] = array(
'#id' => 'edit-separator-replace',
'#type' => 'textfield',
'#title' => t('Separator'),
'#description' => t("Character used to separate words in titles. This will replace any spaces and + characters. Using a space or + character can cause unexpected results. Leave empty if you don't want to replace these characters. This happens after the text above is removed."),
'#maxlength' => 1,
'#size' => 1,
);
$form['add_redirect']['path_case'] = array(
'#id' => 'edit-path-case',
'#type' => 'select',
'#title' => t('Path Case'),
'#description' => t("How to transform the case of the path. This happens after the separator character is replaced."),
'#options' => array(
'No transform' => 'No transform',
'Uppercase' => 'Uppercase',
'Lowercase' => 'Lowercase',
),
'#default_value' => 'No transform',
);
$form['save'] = array(
'#type' => 'submit',
'#value' => t("Submit"),
);
return $form;
}
function taxonomy_redirect_get_php_filter() {
$phpfilter = 0;
$filters = taxonomy_redirect_get_all_filter_formats();
foreach ($filters as $filter) {
if ($filter->name == 'PHP code') {
$phpfilter = $filter->format;
}
}
return $phpfilter;
}
function theme_taxonomy_redirect_redirects_form($form) {
foreach ($form['redirects'] as $i => $redirect) {
if (is_numeric($i)) {
$rows[] = array(
drupal_render($form['redirects'][$i]['vocabulary']),
drupal_render($form['redirects'][$i]['term']),
drupal_render($form['redirects'][$i]['path']),
drupal_render($form['redirects'][$i]['remove_text']),
drupal_render($form['redirects'][$i]['separator']),
drupal_render($form['redirects'][$i]['path_case']),
drupal_render($form['redirects'][$i]['load']),
drupal_render($form['redirects'][$i]['delete']),
drupal_render($form['redirects'][$i]['vid']),
drupal_render($form['redirects'][$i]['tid']),
);
}
}
if (!$rows) {
$rows[] = array(
array(
'data' => t("There are currently no taxonomy redirect entries."),
'colspan' => 6,
),
);
}
$output .= theme('table', array(
t('Vocabulary'),
t('Term'),
t('Path'),
t('Remove Text'),
t('Separator'),
t('Path Case'),
t('View in editor'),
t('delete'),
), $rows);
$output .= drupal_render($form);
return $output;
}
function taxonomy_redirect_redirects_form_validate($form_id, $form) {
if ($form['add_redirect']['filter'] != FILTERED_HTML) {
if (!filter_access($form['add_redirect']['filter'])) {
form_set_error('add_redirect][filter', t('You are not authorised to use this input format'));
}
$phpcode = taxonomy_redirect_get_php_filter();
if ($form['add_redirect']['filter'] == $phpcode) {
$test = _taxonomy_redirect_exec_filter($form['add_redirect']['path'], $form['add_redirect']['filter']);
}
}
$vid = $_POST['vocab_select'];
$any_deletes = FALSE;
if ($form['redirects']) {
foreach ($form['redirects'] as $i => $row) {
if ($row['delete']) {
$any_deletes = TRUE;
}
}
}
if ($any_deletes == FALSE) {
if (!$vid || $vid < 1) {
form_set_error('add_redirect][vocab_select', t("Error: Please select a vocabulary."));
}
if (!$form['add_redirect']['path']) {
form_set_error('add_redirect][path', t("Error: Please enter a path."));
}
}
}
function taxonomy_redirect_redirects_form_submit($form_id, $form) {
$vid = $_POST['vocab_select'];
$tids = isset($_POST['term_select_' . $vid]) ? $_POST['term_select_' . $vid] : array(
NULL,
);
$vocab = taxonomy_get_vocabulary($vid);
$original = $vocab->module;
if ($original == 'taxonomy_redirect') {
$result = db_query("SELECT * \n FROM {taxonomy_redirect}\n WHERE vid = %d", $vid);
$data = db_fetch_object($result);
$original = $data->module;
if ($original == 'taxonomy_redirect' || !$original) {
$original = 'taxonomy';
}
}
$path = $form['add_redirect']['path'];
$path_case = $form_state['values']['add_redirect']['path_case'];
$separator = $form['add_redirect']['separator_replace'];
$remove_text = $form['add_redirect']['remove_text'];
$filter = (int) trim($form['add_redirect']['filter']);
if ($path != '' && $vid > 0) {
db_query("UPDATE {vocabulary} \n SET module = 'taxonomy_redirect' \n WHERE vid = '%d'", $vid);
foreach ($tids as $tid) {
if ($tid > 0) {
db_query("DELETE FROM {taxonomy_redirect} WHERE vid = '%d' AND tid = '%d'", $vid, $tid);
db_query("INSERT INTO {taxonomy_redirect} (vid, tid, module, path, separator_replace, remove_text, filter, path_case) \n VALUES (%d, %d, '%s', '%s', '%s', '%s', %d, '%s')", $vid, $tid, $original, $path, $separator, $remove_text, $filter, $path_case);
}
else {
db_query("DELETE FROM {taxonomy_redirect} WHERE vid = '%d' AND tid is NULL", $vid);
db_query("INSERT INTO {taxonomy_redirect} (vid, tid, module, path, separator_replace, remove_text, filter, path_case) \n VALUES (%d, NULL, '%s', '%s', '%s', '%s', %d, '%s')", $vid, $original, $path, $separator, $remove_text, $filter, $path_case);
}
}
drupal_set_message("Saved redirect");
}
$count_deleted = 0;
if ($form['redirects']) {
foreach ($form['redirects'] as $i => $row) {
if ($row['delete']) {
$vid = $row['vid'];
$tid = $row['tid'];
if ($tid) {
db_query("DELETE FROM {taxonomy_redirect} \n WHERE vid = '%d' \n AND tid = '%d'", $vid, $tid);
}
else {
db_query("DELETE FROM {taxonomy_redirect} \n WHERE vid = '%d' \n AND tid is null", $vid);
}
$count = db_result(db_query("SELECT COUNT(*)\n FROM {taxonomy_redirect}\n WHERE vid = %d", $vid));
if (!$count) {
db_query("UPDATE {vocabulary} \n SET module = 'taxonomy' \n WHERE vid = %d", $vid);
}
$count_deleted++;
}
}
if ($count_deleted > 0) {
drupal_set_message("Redirects deleted");
}
}
return 'admin/build/taxonomy_redirect';
}
function _taxonomy_redirect_get_filters($i = NULL) {
$filters = array(
FILTERED_HTML => t("Plain text"),
);
$phpcode = taxonomy_redirect_get_php_filter();
if (filter_access($phpcode)) {
$filters[$phpcode] = 'PHP Code';
}
if (isset($i)) {
return $filters[$i];
}
return $filters;
}
function _taxonomy_redirect_exec_filter($text, $filter) {
$phpcode = taxonomy_redirect_get_php_filter();
switch ($filter) {
case $phpcode:
return check_markup($text, $phpcode, FALSE);
case FILTERED_HTML:
default:
return $text;
}
}
function taxonomy_redirect_term_path($term) {
$t = taxonomy_get_term($term->tid);
$term->name = isset($term->name) ? $term->name : $t->name;
$term->description = isset($term->descrition) ? $term->description : $t->description;
$term->weight = isset($term->weight) ? $term->weight : $t->weight;
$redirect = db_fetch_object(db_query("SELECT path, separator_replace, remove_text, filter\n FROM {taxonomy_redirect} \n WHERE vid = '%d' \n AND tid = '%d'", $term->vid, $term->tid));
if (!$redirect || !$redirect->path) {
$redirect = db_fetch_object(db_query("SELECT path, separator_replace, remove_text, filter\n FROM {taxonomy_redirect} \n WHERE vid = '%d' \n AND tid IS NULL", $term->vid));
}
if (!$redirect || !$redirect->path) {
return 'taxonomy/term/' . $term->tid;
}
if (substr($redirect->path, 0, 2) == '<?') {
$nid = taxonomy_redirect_get_php_nid_variable();
$text = '<?php ';
$text .= '$tid = ' . $term->tid . '; ';
$text .= '$tname = ' . "'" . $term->name . "'; ";
$text .= '$nid = ' . $nid . '; ';
$openingtag = strpos(strtolower($redirect->path), 'php') + 3;
$text .= substr($redirect->path, $openingtag);
}
else {
$text = $redirect->path;
}
$path = trim(_taxonomy_redirect_exec_filter($text, $redirect->filter));
$separator = $redirect->separator_replace;
$remove_text = $redirect->remove_text;
$path_case = $redirect->path_case;
if (function_exists('taxonomy_redirect_custom_term_path')) {
return taxonomy_redirect_custom_term_path($term, $path, $separator, $remove_text, $path_case);
}
return taxonomy_redirect_default_term_path($term, $path, $separator, $remove_text, $path_case);
}
function taxonomy_redirect_default_term_path($term, $path, $separator = NULL, $remove_text = NULL, $path_case = 'No transform') {
$parents = taxonomy_get_parents_all($term->tid);
$parents = array_reverse($parents);
array_pop($parents);
$parent_path = '';
foreach ($parents as $parent) {
$parent_names = $parent_names ? $parent_names . '/' . $parent->name : $parent->name;
$parent_ids = $parent_ids ? $parent_ids . '/' . $parent->tid : $parent->tid;
}
$path = t($path, array(
'!tid' => $term->tid,
'!name' => $term->name,
'!parent_names' => $parent_names,
'!parent_ids' => $parent_ids,
));
$text = array_filter(preg_split("/\n|\r/", $remove_text), 'taxonomy_redirect_filter_empty_lines');
if (count($text) != 0) {
$path = str_replace($text, "", $path);
}
if ($separator || $separator === '0') {
$path = str_replace(array(
' ',
'+',
), $separator, $path);
}
switch ($path_case) {
case 'No transform':
break;
case 'Uppercase':
$path = strtoupper($path);
break;
case 'Lowercase':
$path = strtolower($path);
break;
}
while (strpos($path, '//') !== FALSE) {
$path = str_replace('//', '/', $path);
}
while (strpos($path, '/') === 0) {
$path = substr($path, 1);
}
return $path;
}
function taxonomy_redirect_filter_empty_lines($var) {
if (ord($var) == 13 || ord($var) == 0) {
return FALSE;
}
else {
return TRUE;
}
}
function taxonomy_redirect_get_all_filter_formats() {
global $user;
static $formats;
if (!isset($formats)) {
$formats = array();
$query = 'SELECT * FROM {filter_formats}';
$result = db_query($query, $args);
while ($format = db_fetch_object($result)) {
$formats[$format->format] = $format;
}
}
return $formats;
}
function taxonomy_redirect_get_php_nid_variable() {
$nid = 0;
$backtrace = debug_backtrace();
foreach ($backtrace as $call) {
if ($nid) {
continue;
}
if ($call['function'] == 'taxonomy_link') {
$nid = $call['args'][1]->nid;
}
if (substr($call['function'], -8, 8) == '_nodeapi') {
$nid = $call['args'][0]->nid;
}
if ($call['function'] == '_phptemplate_render' && array_key_exists('nid', $call['args'][1])) {
$nid = $call['args'][1]['nid'];
}
}
return $nid;
}