the currently active alias. * -- 'redirect' => a boolean flag telling the module to redirect to the * registered domain name if accessed from an alias. */ function domain_alias_domain_bootstrap_lookup($domain) { // If we had an exact match, then $domain['sitename'] is populated. // Otherwise, we must do an advanced check. if (isset($domain['sitename'])) { return; } $alias = domain_alias_lookup($domain['subdomain']); if ($alias != -1) { $domain['domain_id'] = $alias['domain_id']; $domain['active_alias_id'] = $alias['alias_id']; $domain['redirect'] = (boolean) $alias['redirect']; } return $domain; } /** * Implements hook_init(). * * If redirection is enabled for the active domain alias then we redirect to the * main domain. */ function domain_alias_init() { $_domain = domain_get_domain(); // Redirect to main domain if active domain alias is set to redirect. // $_domain['redirect'] gets set in domain_alias_domain_bootstrap_lookup(). if (isset($_domain['redirect']) && $_domain['redirect'] == TRUE) { $domain = domain_lookup($_domain['domain_id']); drupal_goto(domain_get_uri($domain)); } } /** * Implements hook_menu(). */ function domain_alias_menu() { $items = array(); $items['admin/structure/domain/view/%domain/alias'] = array( 'title' => 'Aliases', 'access arguments' => array('administer domains'), 'type' => MENU_LOCAL_TASK, 'page callback' => 'domain_alias', 'page arguments' => array(4), 'file' => 'domain_alias.admin.inc', ); return $items; } /** * Implements hook_theme(). */ function domain_alias_theme() { return array( 'domain_alias_form' => array( 'render element' => 'form', 'file' => 'domain_alias.admin.inc', ), 'domain_alias_block' => array( 'variables' => array('domains' => array()), ), ); } /** * Implements hook_block_info(). */ function domain_alias_block_info() { $blocks = array(); $blocks['domain_alias'] = array( 'info' => t('Domain alias switcher'), ); return $blocks; } /** * Implements hook_block_view(). */ function domain_alias_block_view($delta = '') { $domains = domain_domains(); $output = theme('domain_alias_block', array('domains' => $domains)); $blocks = array( 'subject' => t('Domain alias switcher'), 'content' => $output, ); return $blocks; } /** * Implements hook_block(). */ function domain_alias_block($op = 'list', $delta = 0, $edit = array()) { $blocks = array(); switch ($op) { case 'list': $blocks['domain_alias'] = array( 'info' => t('Domain alias switcher'), 'cache' => BLOCK_CACHE_PER_ROLE, ); break; case 'view': $domains = domain_domains(); $output = 'Test'; $output = theme('domain_alias_block', $domains); $blocks = array( 'subject' => t('Domain alias switcher'), 'content' => $output, ); break; } return $blocks; } /** * Runs a lookup against the {domain_alias} table. One of the two values must * be present. The database result is limited to one row. * * @param $subdomain * The domain to match the patterns in the {domain_alias} table against. Optional. * @param $alias_id * The alias_id taken from {domain_alias}. Optional * @param $reset * A boolean flag to clear the static variable if necessary. * * @return * An array containing the requested row from the {domain_alias} table. * Returns -1 on failure. */ function domain_alias_lookup($subdomain = NULL, $alias_id = NULL, $reset = FALSE ) { static $aliases; // If both are NULL, no lookup can be run. if (is_null($subdomain) && is_null($alias_id)) { return -1; } // Create a unique key so we can static cache all requests. $key = $alias_id . '_' . $subdomain; // Run the lookup, if needed. if (!isset($aliases[$key]) || $reset) { if (is_string($subdomain)) { // First, look for an exact match. $alias = array(); $alias = db_query("SELECT alias_id, domain_id, pattern, redirect FROM {domain_alias} WHERE pattern = :subdomain", array(':subdomain' => $subdomain))->fetchAssoc(); // If that fails, find the closest pattern(s). if (empty($alias)) { $result = db_query("SELECT alias_id, domain_id, pattern, redirect FROM {domain_alias} WHERE :subdomain LIKE pattern", array(':subdomain' => $subdomain), array('fetch' => PDO::FETCH_ASSOC)); // If we returned more than one match, we have to find the most appropriate one. $patterns = array(); foreach ($result as $alias) { $patterns[] = $alias; } if (empty($patterns)) { $alias = array(); } elseif (count($patterns) == 1) { $alias = current($patterns); } else { $alias = domain_alias_best_match($subdomain, $patterns); } } } elseif (intval($alias_id)) { $alias = db_query("SELECT alias_id, domain_id, pattern, redirect FROM {domain_alias} WHERE alias_id = :alias_id", array(':alias_id' => $alias_id))->fetchAssoc(); } // If we found a match, prepare the readable version. if (isset($alias['alias_id'])) { $alias['pattern'] = _domain_alias_placeholders_from_sql($alias['pattern']); $aliases[$key] = $alias; $key2 = $alias['alias_id'] . '_'; $aliases[$key2] =& $aliases[$key]; } else { $aliases[$key] = -1; } } return $aliases[$key]; } /** * Given multiple choices for an alias, find the best match. * * @param $subdomain * The requested subdomain string. * @param $patterns * An array of patterns and aliase data that match the given subdomain string. * * @return * The best match, as an $alias array. */ function domain_alias_best_match($subdomain, $patterns) { $alias = array(); $test = -1; $request = explode('.', $subdomain); foreach ($patterns as $pattern) { $match = explode('.', $pattern['pattern']); $count = count(array_intersect($match, $request)); if ($count > $test) { $test = $count; $alias = $pattern; } } return $alias; } /** * Replace placeholders * and ? with SQL placeholders % and _ * * @param $subdomain * String to work on. * * @return * String with replaced values. */ function _domain_alias_placeholders_to_sql($subdomain, $reverse = FALSE) { $placeholders = array('*' => '%', '?' => '_'); if ($reverse) { return str_replace($placeholders, array_keys($placeholders), $subdomain); } else { return str_replace(array_keys($placeholders), $placeholders, $subdomain); } } /** * Replace SQL placeholders % and _ by placeholders * and ?. * Opposite of _domain_alias_placeholder_to_sql(). * * @param $subdomain * String to work on. * * @return * String with replaced values. */ function _domain_alias_placeholders_from_sql($subdomain) { return _domain_alias_placeholders_to_sql($subdomain, TRUE); } /** * Returns all aliases for one domain record (domain_id). * * @param $domain_id * The domain_id taken from {domain}. * @param $reset * A boolean flag indicating whether to reset the static array or not. * * @return * An array of all aliases defined for given domain_id, indexed by alias_id */ function domain_alias_list($domain_id, $reset = FALSE) { static $aliases, $result; // Query the db for aliases. if (!isset($result) || $reset) { $result = db_query("SELECT domain_id, alias_id, pattern, redirect FROM {domain_alias}", array(), array('fetch' => PDO::FETCH_ASSOC))->FetchAll(); } if (!isset($aliases[$domain_id]) || $reset) { $aliases[$domain_id] = array(); foreach ($result as $data) { $data['pattern'] = _domain_alias_placeholders_from_sql($data['pattern']); $aliases[$data['domain_id']][$data['alias_id']] = $data; } } return $aliases[$domain_id]; } /** * Theme element for the Domain Alias switcher block. * * @param $domains * The array of active domains defined by domain_domains(). * * @return * HTML output. */ function theme_domain_alias_block($variables) { $_domain = domain_get_domain(); $domains = $variables['domains']; $output = ''; $items = array(); $msg = FALSE; $i = 0; $active = NULL; foreach ($domains as $domain) { if ($domain['valid']) { $title = $domain['sitename']; $allow = TRUE; } else { $title = $domain['sitename'] . ' *'; $allow = FALSE; if (user_access('access inactive domains')) { $msg = TRUE; $allow = TRUE; } } if ($allow) { if ($domain['domain_id'] == $_domain['domain_id']) { $title = '' . $title . ''; } $items[$i]['data'] = l($title, domain_get_uri($domain), array('absolute' => TRUE, 'html' => TRUE)); if (!empty($domain['aliases'])) { $request = array_reverse(explode('.', $_domain['subdomain'])); if (isset($_domain['active_alias_id'])) { $active = $_domain['active_alias_id']; } foreach ($domain['aliases'] as $alias_id => $alias) { $items[$i]['children'][] = _domain_alias_link($alias, $domain, $request, $active); } } $i++; } } $output .= theme('item_list', array('items' => $items)); if ($msg) { $output .= t('* Inactive domain.'); } return $output; } /** * Format links for the switcher block. * * @param $alias * The alias array to check. * @param $domain * The parent domain of the alias. * @param $request * A reversed array of the HTTP_HOST request, used for replacement strings. * @param $active * The active alias id, if present. * * @return * A link or plain text representation of the alias. */ function _domain_alias_link($alias, $domain, $request, $active = 0) { // Search for wildcards. $wildcard = substr_count($alias['pattern'], '*'); $character = substr_count($alias['pattern'], '?'); $text = $alias['pattern']; if ($wildcard) { $bits = array_reverse(explode('.', $text)); foreach ($bits as $key => $bit) { if ($bit == '*' && isset($request[$key])) { $bits[$key] = $request[$key]; } } $text = implode('.', array_reverse($bits)); } if ($character) { $request = strrev(implode('.', array_reverse($request))); $char = strpos(strrev($text), '?'); $replace = substr($request, $char, 1); $text = str_replace('?', $replace, $text); } $wildcard = substr_count($text, '*'); $output = $alias['pattern']; if ($alias['alias_id'] == $active) { $output = '' . $alias['pattern'] . ''; } if (!$alias['redirect'] && !$wildcard) { $domain['subdomain'] = $text; $path = domain_get_uri($domain); $link = l($output, $path, array('absolute' => TRUE, 'html' => TRUE)); } else { $link = check_markup($output); } return $link; }