View source
<?php
define('CONTEXT_PREFIX_PATH', 0);
define('CONTEXT_PREFIX_SUBDOMAIN', 1);
define('CONTEXT_PREFIX_DOMAIN', 2);
define('CONTEXT_PREFIX_PAIR', 3);
function context_prefix_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'type' => module_exists('context_ui') ? MENU_LOCAL_TASK : MENU_NORMAL_ITEM,
'title' => t('Context prefix'),
'description' => t('Settings for context prefix.'),
'path' => 'admin/build/context/prefix',
'callback' => 'drupal_get_form',
'callback arguments' => array(
'context_prefix_settings_form',
),
'access' => user_access('administer site configuration'),
'weight' => 10,
);
$items[] = array(
'type' => MENU_DEFAULT_LOCAL_TASK,
'title' => t('Settings'),
'path' => 'admin/build/context/prefix/settings',
'callback arguments' => array(
'context_prefix_settings_form',
),
'access' => user_access('administer site configuration'),
'weight' => 0,
);
$items[] = array(
'type' => MENU_LOCAL_TASK,
'title' => t('Registered prefixes'),
'path' => 'admin/build/context/prefix/list',
'callback' => 'context_prefix_admin',
'access' => user_access('administer site configuration'),
'weight' => 10,
);
}
return $items;
}
function context_prefix_init() {
static $once;
if (!$once) {
_context_prefix_init(CONTEXT_PREFIX_PATH);
_context_prefix_init(CONTEXT_PREFIX_DOMAIN);
_context_prefix_init(CONTEXT_PREFIX_PAIR);
$once = true;
}
}
function _context_prefix_init($method = CONTEXT_PREFIX_PATH) {
switch ($method) {
case CONTEXT_PREFIX_PATH:
$q = isset($_REQUEST["q"]) ? trim($_REQUEST["q"], "/") : '';
$parsed = context_prefix_parse(CONTEXT_PREFIX_PATH, $q);
break;
case CONTEXT_PREFIX_PAIR:
$q = isset($_REQUEST["q"]) ? trim($_REQUEST["q"], "/") : '';
$parsed = context_prefix_parse(CONTEXT_PREFIX_PAIR, $q);
break;
case CONTEXT_PREFIX_DOMAIN:
$host = $_SERVER['HTTP_HOST'];
$q = str_replace('http://', '', $host);
$parsed = context_prefix_parse(CONTEXT_PREFIX_DOMAIN, $q);
break;
}
if (in_array($method, array(
CONTEXT_PREFIX_PATH,
CONTEXT_PREFIX_PAIR,
)) && $_GET['q'] == $_REQUEST['q']) {
$q = context_prefix_unprefix($q, $method);
if ($q == '') {
$_GET['q'] = variable_get('site_frontpage', 'node');
}
else {
$_REQUEST['q'] = $_GET['q'] = _context_prefix_get_normal_path($q);
}
}
if (is_array($parsed)) {
foreach ($parsed as $prefix => $info) {
context_prefix_set($method, $prefix, $info);
}
}
}
if (!function_exists('custom_url_rewrite')) {
function custom_url_rewrite($type, $path, $original) {
return context_prefix_url_rewrite($type, $path, $original);
}
}
function context_prefix_url_rewrite($type, $path, $original) {
$working_path = $path;
$args = array();
if (!clswitch('get')) {
$active_path_prefixes = array();
foreach (context_prefix_get(CONTEXT_PREFIX_PAIR) as $item) {
$active_path_prefixes[] = $item['prefix'] . '/' . $item['id'];
}
foreach (context_prefix_get(CONTEXT_PREFIX_PATH) as $item) {
$active_path_prefixes[] = $item['prefix'];
}
if (count($active_path_prefixes)) {
$parsed = context_prefix_parse(CONTEXT_PREFIX_PATH, $working_path) + context_prefix_parse(CONTEXT_PREFIX_PAIR, $working_path);
if (!$options['alias'] && !strpos($path, '://') && !count($parsed) && count($active_path_prefixes)) {
$args = $args + $active_path_prefixes;
}
}
}
if ($working_path) {
$args[] = $working_path;
}
return is_array($args) ? implode('/', $args) : '';
}
function context_prefix_prefixes($requested_method = CONTEXT_PREFIX_PATH, $reset = FALSE) {
static $prefixes;
if (!isset($prefixes) || $reset) {
$prefixes = array();
foreach (module_invoke_all('context_prefix_prefixes') as $provider => $items) {
$method = variable_get('context_prefix_method_' . $provider, CONTEXT_PREFIX_PATH);
if ($method == CONTEXT_PREFIX_PAIR) {
$prefix = variable_get('context_prefix_method_' . $provider . '_key', false);
if ($prefix != false) {
$prefixes[$method][$prefix] = array(
'provider' => $provider,
'id' => null,
);
}
}
else {
foreach ($items as $item) {
if ($item['prefix'] && $item['id']) {
$prefixes[$method][$item['prefix']] = array(
'provider' => $provider,
'id' => $item['id'],
);
}
}
}
}
$result = db_query("SELECT DISTINCT(provider) FROM {context_prefix}");
while ($item = db_fetch_object($result)) {
$method = variable_get('context_prefix_method_' . $item->provider, CONTEXT_PREFIX_PATH);
if ($method == CONTEXT_PREFIX_PAIR) {
$prefix = variable_get('context_prefix_method_' . $item->provider . '_key', false);
if ($prefix != false) {
$prefixes[$method][$prefix] = array(
'provider' => $item->provider,
'id' => null,
);
}
}
else {
$result2 = db_query("SELECT * FROM {context_prefix} WHERE provider = '%s'", $item->provider);
while ($row = db_fetch_object($result2)) {
$prefixes[$method][$row->prefix] = array(
'provider' => $row->provider,
'id' => $row->id,
);
}
}
}
}
return isset($prefixes[$requested_method]) ? $prefixes[$requested_method] : array();
}
function context_prefix_parse($method = CONTEXT_PREFIX_PATH, $q) {
static $cache;
if (!isset($cache[$method][$q])) {
$valid_prefixes = context_prefix_prefixes($method);
switch ($method) {
case CONTEXT_PREFIX_PATH:
case CONTEXT_PREFIX_PAIR:
$parsed = array();
$args = explode('/', $q);
$arg = $args[0];
while (isset($valid_prefixes[$arg])) {
$parsed[$arg] = $valid_prefixes[$arg];
array_shift($args);
if ($method == CONTEXT_PREFIX_PAIR) {
$parsed[$arg]['id'] = array_shift($args);
}
$arg = $args[0];
if (in_array($arg, $parsed)) {
break;
}
}
$cache[$method][$q] = $parsed;
break;
case CONTEXT_PREFIX_DOMAIN:
$parsed = array();
if (isset($valid_prefixes[$q])) {
$parsed[$q] = $valid_prefixes[$q];
}
$cache[$method][$q] = $parsed;
break;
}
}
return $cache[$method][$q];
}
function context_prefix_unprefix($q, $method, $providers = array()) {
$parsed = context_prefix_parse($method, $q);
if (is_array($providers) && count($providers)) {
foreach ($parsed as $prefix => $info) {
if (!in_array($info['provider'], $providers)) {
unset($parsed[$prefix]);
}
}
}
$parsed = array_keys($parsed);
$args = explode('/', $q);
switch ($method) {
case CONTEXT_PREFIX_PATH:
$args = array_diff($args, $parsed);
break;
case CONTEXT_PREFIX_PAIR:
foreach ($parsed as $v) {
array_splice($args, array_search($v, $args), 2);
}
break;
}
return implode('/', $args);
}
function context_prefix_providers($by_method = FALSE) {
static $providers;
if (!is_array($providers)) {
$providers = array();
$providers = module_invoke_all('context_prefix_provider');
}
if ($by_method) {
static $methods;
if (!isset($methods)) {
$methods = new context_prefix_cache();
foreach ($providers as $id => $provider) {
$methods
->add(variable_get('context_prefix_method_' . $id, CONTEXT_PREFIX_PATH), array(
$id => $provider,
));
}
}
return $methods
->get();
}
else {
return $providers;
}
}
function _context_prefix_get_normal_path($path) {
if (!function_exists('drupal_get_headers')) {
return $path;
}
elseif ($alias = drupal_lookup_path('source', $path)) {
return $alias;
}
else {
return $path;
}
}
function _context_prefix_set($op = 'set', $type = CONTEXT_PREFIX_PATH, $prefix = '', $info = array()) {
static $used;
if (!$used) {
$used = new context_prefix_cache();
}
switch ($op) {
case 'set':
$info['prefix'] = $prefix;
$used
->add($type, $info, false);
if ($info['provider'] && $info['id']) {
$providers = context_prefix_providers();
$callback = $providers[$info['provider']]['callback'];
$args = isset($providers[$info['provider']]['callback arguments']) ? $providers[$info['provider']]['callback arguments'] : array();
$args[] = $info['id'];
if (function_exists($callback)) {
call_user_func_array($callback, $args);
}
}
break;
case 'get':
if ($type === 'all') {
return $used
->get();
}
else {
return $used
->get($type);
}
}
}
function context_prefix_set($type = CONTEXT_PREFIX_PATH, $prefix = '', $info = array()) {
return _context_prefix_set('set', $type, $prefix, $info);
}
function context_prefix_get($type = CONTEXT_PREFIX_PATH) {
return _context_prefix_set('get', $type);
}
function context_prefix_admin() {
global $pager_page_array, $pager_total, $pager_total_items;
$page = isset($_GET['page']) ? $_GET['page'] : 0;
$element = 0;
$limit = 20;
$pager_page_array = array(
$page,
);
$methods = _context_ui_options();
$merged = array();
foreach (array_keys($methods) as $method) {
foreach (context_prefix_prefixes($method) as $prefix => $info) {
$info['prefix'] = $prefix;
$merged[] = $info;
}
}
$rows = array();
for ($i = $page * $limit; $i < ($page + 1) * $limit && $i < count($merged); $i++) {
$rows[] = array(
$merged[$i]['provider'],
$merged[$i]['prefix'],
$merged[$i]['id'],
$methods[variable_get('context_prefix_method_' . $merged[$i]['provider'], CONTEXT_PREFIX_PATH)],
);
}
$pager_total_items[$element] = count($merged);
$pager_total[$element] = ceil($pager_total_items[$element] / $limit);
$pager_page_array[$element] = max(0, min((int) $pager_page_array[$element], (int) $pager_total[$element] - 1));
if ($rows) {
$output .= theme('table', array(
t('Provider'),
t('Prefix'),
t('ID'),
t('Method'),
), $rows);
$output .= theme('pager');
}
else {
$output .= "<p>" . t('No context prefixes have been registered.') . "</p>";
}
return $output;
}
function context_prefix_settings_form() {
global $base_url;
$form = array();
$options = _context_ui_options();
foreach (context_prefix_providers() as $id => $provider) {
if (is_array($provider['methods']) && count($provider['methods'])) {
$provider_options = array();
foreach ($provider['methods'] as $method) {
$provider_options[$method] = $options[$method];
}
}
else {
$provider_options = $options;
}
$form[$id] = array(
'#fieldset' => true,
'#provider' => true,
'#title' => $provider['name'],
'#description' => $provider['description'],
);
$form[$id]['context_prefix_method_' . $id] = array(
'#title' => t('Method'),
'#type' => 'select',
'#options' => $provider_options,
'#default_value' => variable_get('context_prefix_method_' . $id, CONTEXT_PREFIX_PATH),
);
$form[$id]['context_prefix_method_' . $id . '_key'] = array(
'#title' => t('Key'),
'#type' => 'textfield',
'#size' => 12,
'#default_value' => variable_get('context_prefix_method_' . $id . '_key', ''),
);
}
$form['context_prefix_location'] = array(
'#type' => 'fieldset',
'#title' => t('Prefix location settings'),
);
$form['context_prefix_location']['context_prefix_base_domain'] = array(
'#type' => 'textfield',
'#title' => t('Select base domain'),
'#description' => t('This setting determines the base domain for domain based context prefixing.'),
'#required' => FALSE,
'#default_value' => variable_get('context_prefix_base_domain', $base_url),
);
$form = system_settings_form($form);
$form['#theme'] = 'context_prefix_settings_form';
return $form;
}
function theme_context_prefix_settings_form($form) {
$output = '';
$rows = array();
foreach (element_children($form) as $id) {
$row = array();
if (isset($form[$id]['#provider'])) {
$name = $form[$id]['#title'];
$description = $form[$id]['#description'];
unset($form[$id]['#title']);
unset($form[$id]['#description']);
$row[] = "<strong>{$name}</strong><div class='description'>{$description}</div>";
foreach (element_children($form[$id]) as $item) {
unset($form[$id][$item]['#title']);
$row[] = drupal_render($form[$id][$item]);
}
}
$rows[] = $row;
}
$output .= theme('table', array(
t('Provider'),
t('Prefix method'),
t('Key'),
), $rows);
$output .= drupal_render($form);
drupal_add_js(drupal_get_path("module", "context_prefix") . "/context_prefix_admin.js");
return $output;
}
function context_prefix_api($op = 'insert', $context) {
switch ($op) {
case 'load':
if (isset($context['provider'])) {
if ($context['id']) {
$context = db_fetch_array(db_query("SELECT * FROM {context_prefix} WHERE id = '%s' AND provider = '%s'", $context['id'], $context['provider']));
if ($context) {
return $context;
}
}
else {
if ($context['prefix']) {
$context = db_fetch_array(db_query("SELECT * FROM {context_prefix} WHERE prefix = '%s' AND provider = '%s'", $context['prefix'], $context['provider']));
if ($context) {
return $context;
}
}
}
return false;
}
break;
case 'validate':
if (check_plain($context['provider']) && preg_match('!^[a-z0-9_-]+$!', $context['prefix'])) {
$id = db_result(db_query("SELECT id FROM {context_prefix} WHERE prefix = '%s'", $context['prefix']));
if ($id && $id == $context['id']) {
return true;
}
else {
if (!$id) {
return true;
}
}
return false;
}
else {
return false;
}
case 'insert':
if (context_prefix_api('validate', $context)) {
$status = db_query("INSERT INTO {context_prefix} (provider, prefix, id) VALUES ('%s', '%s', %d)", $context['provider'], $context['prefix'], $context['id']);
return $status;
}
return false;
case 'update':
if (context_prefix_api('validate', $context)) {
$status = db_query("UPDATE {context_prefix} SET prefix = '%s' WHERE id = '%s' AND provider = '%s'", $context['prefix'], $context['id'], $context['provider']);
return $status;
}
case 'delete':
if ($context['prefix']) {
$param = 'prefix';
$where = $context['prefix'];
}
else {
if ($context['id']) {
$param = 'id';
$where = $context['id'];
}
}
$check = db_result(db_query("SELECT id FROM {context_prefix} WHERE provider = '%s' AND {$param} = '%s'", $context['provider'], $where));
if ($check) {
$status = db_query("DELETE FROM {context_prefix} WHERE provider = '%s' AND {$param} = '%s'", $context['provider'], $where);
return $status;
}
return false;
}
return false;
}
function context_prefix_goto($provider, $id, $path = '', $query = NULL, $fragment = NULL, $http_response_code = 302) {
$method = variable_get('context_prefix_method_' . $provider, CONTEXT_PREFIX_PATH);
$prefixes = context_prefix_prefixes($method);
switch ($method) {
case CONTEXT_PREFIX_PATH:
foreach ($prefixes as $key => $info) {
if ($info['id'] == $id) {
clswitch('set', true);
$path = $key . '/' . $path;
break;
}
}
break;
case CONTEXT_PREFIX_PAIR:
clswitch('set', true);
$prefixes = array_keys($prefixes);
$path = $prefixes[0] . '/' . $id . '/' . $path;
break;
case CONTEXT_PREFIX_DOMAIN:
foreach ($prefixes as $key => $info) {
if ($info['id'] == $id) {
$path = 'http://' . $key . '/' . $path;
break;
}
}
break;
}
drupal_goto($path, $query, $fragment, $http_response_code);
}
function cl($text, $path, $attributes = array(), $query = NULL, $fragment = NULL, $absolute = FALSE, $html = FALSE, $dropcontext = FALSE) {
global $base_url;
clswitch('set', $dropcontext);
if (!$dropcontext && $path == '<front>') {
$path = context_prefix_url_rewrite('alias', '', '');
}
if ($dropcontext) {
$absolute = TRUE;
if ($path == '<front>') {
$path = variable_get('site_frontpage', 'node');
}
if ($domain = variable_get('context_prefix_base_domain', '')) {
$path = $domain . '/' . $path;
}
}
$l = l($text, $path, $attributes, $query, $fragment, $absolute, $html);
clswitch('reset');
return $l;
}
function clswitch($op, $absolute = null) {
static $drop;
switch ($op) {
case 'set':
$drop = $absolute;
break;
case 'get':
return $drop;
break;
case 'reset':
$drop = null;
break;
}
}
function theme_context_links($links, $attributes = array(
'class' => 'links',
)) {
$output = '';
if (count($links) > 0) {
$output = '<ul' . drupal_attributes($attributes) . '>';
$num_links = count($links);
$i = 1;
foreach ($links as $key => $link) {
$class = '';
if (isset($link['attributes']) && isset($link['attributes']['class'])) {
$link['attributes']['class'] .= ' ' . $key;
$class = $key;
}
else {
$link['attributes']['class'] = $key;
$class = $key;
}
if (stristr($key, 'active')) {
$class .= " active";
}
$extra_class = '';
if ($i == 1) {
$extra_class .= 'first ';
}
if ($i == $num_links) {
$extra_class .= 'last ';
}
$output .= '<li class="' . $extra_class . $class . '">';
$html = isset($link['html']) && $link['html'];
$link['query'] = isset($link['query']) ? $link['query'] : NULL;
$link['fragment'] = isset($link['fragment']) ? $link['fragment'] : NULL;
if (isset($link['href'])) {
if ($link['warp']) {
$output .= cl($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment'], FALSE, $html, TRUE);
}
else {
$output .= l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment'], FALSE, $html);
}
}
else {
if ($link['title']) {
if (!$html) {
$link['title'] = check_plain($link['title']);
}
$output .= '<span' . drupal_attributes($link['attributes']) . '>' . $link['title'] . '</span>';
}
}
$i++;
$output .= "</li>\n";
}
$output .= '</ul>';
}
return $output;
}
function context_prefix_form($provider, $id, $prefix = '') {
switch (variable_get('context_prefix_method_' . $provider, CONTEXT_PREFIX_PATH)) {
case CONTEXT_PREFIX_PATH:
case CONTEXT_PREFIX_PAIR:
$description = t('Choose a prefix path. May contain only lowercase letters, numbers, dashes and underscores. e.g. "my-prefix"');
break;
case CONTEXT_PREFIX_SUBDOMAIN:
$description = t('Enter a domain registered for this context, such as "mygroup". Do not include http://');
break;
case CONTEXT_PREFIX_DOMAIN:
$description = t('Enter a domain registered for this context, such as "www.example.com". Do not include http://');
break;
}
$form = array(
'#tree' => TRUE,
'#validate' => array(
'context_prefix_form_validate' => array(),
),
);
$form['prefix'] = array(
'#title' => t('Path prefix'),
'#type' => 'textfield',
'#description' => $description,
'#maxlength' => 255,
'#required' => true,
'#default_value' => $prefix,
);
$form['provider'] = array(
'#type' => 'value',
'#value' => $provider,
);
$form['id'] = array(
'#type' => 'value',
'#value' => $id,
);
return $form;
}
function context_prefix_form_validate($form) {
$definition = array(
'provider' => $form['provider']['#value'],
'prefix' => $form['prefix']['#value'],
'id' => $form['id']['#value'],
);
if (!context_prefix_api('validate', $definition)) {
form_set_error($form['#parents'][0], t('There was an error registering the prefix "@prefix". It is either invalid or is already taken. Please choose another.', array(
'@prefix' => $form['prefix']['#value'],
)));
return false;
}
else {
return true;
}
}
class context_prefix_cache {
protected $cache = array();
function __construct() {
$this->cache[CONTEXT_PREFIX_PATH] = array();
$this->cache[CONTEXT_PREFIX_PAIR] = array();
$this->cache[CONTEXT_PREFIX_SUBDOMAIN] = array();
$this->cache[CONTEXT_PREFIX_DOMAIN] = array();
}
public function add($method, $item, $merge = true) {
if (is_array($item) && $merge) {
$this->cache[$method] = $this->cache[$method] + $item;
}
else {
$this->cache[$method][] = $item;
}
}
public function get($method = false, $id = false) {
if ($method !== false && $id !== false) {
return isset($this->cache[$method][$id]) ? $this->cache[$method][$id] : false;
}
elseif ($method !== false) {
return $this->cache[$method];
}
else {
return $this->cache;
}
}
}
function _context_ui_options() {
return array(
CONTEXT_PREFIX_PATH => t('Path'),
CONTEXT_PREFIX_PAIR => t('Keyed pair'),
CONTEXT_PREFIX_DOMAIN => t('Full domain'),
);
}