domain_path.module in Domain Path 6
Same filename and directory in other branches
Path alias handling for multiple domains.
File
domain_path.moduleView source
<?php
/**
* @file
* Path alias handling for multiple domains.
*/
/**
* Implements hook_perm().
*/
function domain_path_perm() {
return array(
'edit domain paths',
);
}
/**
* Implements hook_domainpath().
*/
function domain_path_domainpath($domain_id, &$path, $path_language = '') {
$domain = domain_get_domain();
$did = $domain['domain_id'];
$alias = $path;
$paths = domain_path_paths('alias');
if (isset($paths[$path][$did])) {
$alias = $paths[$path][$did];
$nid = arg(1, $alias);
}
else {
$nid = domain_path_is_node_path($alias, $path_language);
$alias = "node/{$nid}";
}
if (empty($nid)) {
return;
}
$paths = domain_path_paths('nid', $nid);
if (isset($paths[$domain_id])) {
$path = $paths[$domain_id];
}
else {
$path = drupal_get_path_alias($alias, $path_language);
}
$options['alias'] = TRUE;
}
/**
* Implements hook_boot
*/
function domain_path_boot() {
return;
}
/**
* Implements hook_url_inbound_alter().
*/
function domain_path_url_inbound_alter(&$path, $original_path, $path_language) {
$domain = domain_get_domain();
$did = $domain['domain_id'];
$paths = domain_path_paths('alias');
if (!isset($paths[$original_path][$did])) {
return;
}
$path = $paths[$original_path][$did];
}
/**
* Tell us if the given path is a node link.
*/
function domain_path_is_node_path($path, $language) {
$lookup = drupal_lookup_path('source', $path, $language);
if (!empty($lookup)) {
$path = $lookup;
}
if (arg(0, $path) != 'node') {
return NULL;
}
$arg2 = arg(2, $path);
if (!empty($arg2)) {
return NULL;
}
$arg1 = intval(arg(1, $path));
if (empty($arg1)) {
return NULL;
}
return $arg1;
}
/**
* Return an array of all paths.
*
* We cache this for performance.
*
* @param $key
* The type of data to return. Currently, 'nid' returns an array
* keyed by node id. 'alias' returns an array keyed by path alias.
* @param $nid
* A specific node id to return alias matches.
* @param $reset
* Boolean value to reset the static variable.
* @return
* An array of matches.
*/
function domain_path_paths($key = 'nid', $nid = NULL, $reset = FALSE) {
static $paths;
// Cache routine. Only run this once.
if (!isset($paths) || $reset) {
// Try to get the data from cache.
$cache = cache_get('domain_path');
if (isset($cache->data)) {
$paths = $cache->data;
}
// No cache, run the database query.
if (!isset($paths)) {
$paths = array(
'nid' => array(),
'alias' => array(),
);
// TODO: better handling for different entities.
// TODO: Language support!
$result = db_query("SELECT domain_id, source, alias, language, entity_type, entity_id FROM {domain_path} WHERE entity_type = 'node'");
while ($path = db_fetch_object($result)) {
$paths['nid'][$path->entity_id][$path->domain_id] = $path->alias;
$paths['alias'][$path->alias][$path->domain_id] = $path->source;
}
// Cache for performance.
// TODO: test.
cache_set('domain_path', $paths);
// Return data for a single node?
}
}
// If returning results for a single node, pass back only matches.
if (!is_null($nid)) {
if (!isset($paths[$key][$nid])) {
$paths[$key][$nid] = array();
}
return $paths[$key][$nid];
}
// Return requested data.
return $paths[$key];
}
/**
* Implements hook_form_alter().
*/
function domain_path_form_alter(&$form, $form_state, $form_id) {
// Apply to all node editing forms, but make sure we are not on the CCK field configuration form.
if ($form['#id'] != 'node-form' || isset($form['#node']->cck_dummy_node_form)) {
return;
}
cache_clear_all('domain_path', 'cache');
// This lets CCK adjust the weight of our element using domain_content_extra_fields().
$weight = module_exists('content') ? content_extra_field_weight($form['type']['#value'], 'domain_path') : 31;
$form['domain_path'] = array(
'#tree' => TRUE,
'#title' => t('Domain-specific paths'),
'#type' => 'fieldset',
'#weight' => $weight,
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#access' => user_access('edit domain paths'),
);
$paths = array();
$domains = domain_domains();
$default_domain = domain_default();
$current = t('<none>');
if (!empty($form['#node']->nid)) {
$current = drupal_get_path_alias('node/' . $form['#node']->nid);
$paths = domain_path_paths('nid', $form['#node']->nid);
}
$form['domain_path']['current'] = array(
'#type' => 'item',
'#title' => t('Current alias'),
'#markup' => check_plain($current),
);
$form['domain_path']['domain_path_ignore'] = array(
'#type' => 'checkbox',
'#title' => t('Delete domain-specific aliases'),
'#default_value' => FALSE,
);
foreach ($domains as $domain_id => $domain) {
$default = '';
// TODO: Only exposed checked domains?
$form['domain_path'][$domain_id] = array(
'#type' => 'textfield',
'#title' => check_plain($domain['path']),
'#default_value' => isset($paths[$domain_id]) ? $paths[$domain_id] : $default,
'#access' => user_access('edit domain paths'),
);
}
}
/**
* Implements hook_nodeapi().
*/
function domain_path_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
case 'validate':
$form = $a3;
$ignore = $form['domain_path']['domain_path_ignore']['#value'];
if (!empty($ignore)) {
return;
}
$set_message = FALSE;
$dids = array_keys(domain_domains());
$paths = array();
foreach ($dids as $did) {
$paths[$did] = $form['domain_paths'][$did]['#value'];
}
$alias = $form['path']['path']['#value'];
// Make sure we don't duplicate anything.
foreach ($paths as $domain_id => $path) {
$key = $domain_id == -1 ? 0 : $domain_id;
if (!empty($path) && $path == $alias) {
form_set_error("domain_path][{$key}", t('Domain path may not match default path alias. You may leave the element blank.'));
$set_message = TRUE;
}
elseif (!empty($path)) {
$query = db_query("SELECT COUNT(dpid) FROM {domain_path}\n WHERE domain_id = %d\n AND alias = %s\n AND language = %s\n AND source != %s", $key, $path, isset($node->language) ? $node->language : LANGUAGE_NONE, "node/{$node->nid}");
if (db_result($query) > 0) {
form_set_error("domain_path][{$key}", t('Domain path matches an existing domain path alias.'));
}
}
}
// Check for duplicates.
if (module_exists('pathauto') && !empty($node->pathauto_perform_alias)) {
module_load_include('inc', 'pathauto');
$placeholders = pathauto_get_placeholders('node', $node);
$placeholders = array_combine($placeholders['tokens'], $placeholders['values']);
$new_path = pathauto_create_alias('node', 'return', $placeholders, 'node/' . $node->nid, $node->nid, $node->type, $node->language);
}
else {
$new_path = $node->path;
}
// Check to see if pathauto added a -0 to the alias.
// In these cases, we try to notify the end user.
$path = explode('-', $new_path);
$end = array_pop($path);
$num = intval($end);
if (drupal_strlen($num) == drupal_strlen($end) && ($num == $end || $end === 0)) {
$alias = implode('-', $path);
}
else {
$alias = $new_path;
}
// Ensure that the submitted alias does not exist yet.
$query = db_query_range("SELECT 1 FROM {url_alias} WHERE dst = '%s' AND language = '%s' AND src <> '%s'", $alias, $node->language, 'node/' . $node->nid, 0, 1);
$count = db_result($query);
if ($count) {
// If there are no aliases for the active domains, we have to ensure
// that this is not a duplicate alias.
$domains = array_filter($node->domains);
$set_paths = array_filter($paths);
if (empty($domains)) {
form_set_error('domain_path', t('The path alias is already in use. You may provide a domain-specific alias below.'));
$set_message = TRUE;
}
elseif (empty($set_paths)) {
foreach ($domains as $domain_id) {
$key = $domain_id == -1 ? 0 : $domain_id;
form_set_error("domain_path][{$key}", t('The path alias %alias is already in use. You should provide a domain-specific alias.', array(
'%alias' => $alias,
)));
$set_message = TRUE;
}
}
}
if ($set_message) {
drupal_set_message(t('If you choose to use the current alias, the path to this page will be: %alias', array(
'%alias' => $new_path,
)), 'error', FALSE);
}
break;
case 'insert':
case 'update':
if (empty($node->domain_path)) {
return;
}
// Delete existing aliases.
domain_path_nodeapi($node, 'delete');
// If not set to revert, then save changes.
if (empty($node->domain_path['domain_path_ignore'])) {
unset($node->domain_path['domain_path_ignore']);
foreach ($node->domain_path as $domain_id => $path) {
if (!empty($path)) {
$record = array(
'domain_id' => $domain_id,
'source' => "node/{$node->nid}",
'alias' => $path,
'language' => isset($node->language) ? $node->language : LANGUAGE_NONE,
'entity_type' => 'node',
'entity_id' => $node->nid,
);
drupal_write_record('domain_path', $record);
}
}
}
// Rebuild the node alias.
cache_clear_all('domain_path', 'cache');
domain_path_paths('nid', NULL, TRUE);
break;
case 'delete':
db_query("DELETE FROM {domain_path} where entity_type = 'node' AND entity_id = %d", $node->nid);
cache_clear_all('domain_path', 'cache');
break;
}
}
/**
* Implement hook_content_extra_fields()
*
* CCK hook to allow sorting of the domain settings field.
*/
function domain_path_content_extra_fields($type_name = NULL) {
if (!empty($type_name)) {
return array(
'domain_path' => array(
'label' => t('Domain path'),
'description' => t('Domain-specific path settings.'),
'weight' => 31,
),
);
}
}
Functions
Name | Description |
---|---|
domain_path_boot | Implements hook_boot |
domain_path_content_extra_fields | Implement hook_content_extra_fields() |
domain_path_domainpath | Implements hook_domainpath(). |
domain_path_form_alter | Implements hook_form_alter(). |
domain_path_is_node_path | Tell us if the given path is a node link. |
domain_path_nodeapi | Implements hook_nodeapi(). |
domain_path_paths | Return an array of all paths. |
domain_path_perm | Implements hook_perm(). |
domain_path_url_inbound_alter | Implements hook_url_inbound_alter(). |