summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--context_prefix/context_prefix.module304
-rw-r--r--context_prefix/context_prefix_admin.js30
2 files changed, 256 insertions, 78 deletions
diff --git a/context_prefix/context_prefix.module b/context_prefix/context_prefix.module
index c8c8b51..6d97464 100644
--- a/context_prefix/context_prefix.module
+++ b/context_prefix/context_prefix.module
@@ -4,6 +4,7 @@
define('CONTEXT_PREFIX_PATH', 0);
define('CONTEXT_PREFIX_SUBDOMAIN', 1);
define('CONTEXT_PREFIX_DOMAIN', 2);
+define('CONTEXT_PREFIX_PAIR', 3);
/**
* Implementation of hook_menu().
@@ -50,6 +51,7 @@ function context_prefix_init() {
if (!$once) {
_context_prefix_init(CONTEXT_PREFIX_PATH);
_context_prefix_init(CONTEXT_PREFIX_DOMAIN);
+ _context_prefix_init(CONTEXT_PREFIX_PAIR);
$once = true;
}
}
@@ -62,19 +64,10 @@ function _context_prefix_init($method = CONTEXT_PREFIX_PATH) {
case CONTEXT_PREFIX_PATH:
$q = isset($_REQUEST["q"]) ? trim($_REQUEST["q"], "/") : '';
$parsed = context_prefix_parse(CONTEXT_PREFIX_PATH, $q);
- // if $_GET and $_REQUEST are different, the path has NOT been
- // aliased. We may need to rewrite the path.
- if ($_GET['q'] == $_REQUEST['q']) {
- $q = context_prefix_unprefix($q);
- // there is nothing beyond the path prefix -- treat as frontpage
- if ($q == '') {
- $_GET['q'] = variable_get('site_frontpage', 'node');
- }
- // pass the rest of the path onto Drupal cleanly
- else {
- $_REQUEST['q'] = $_GET['q'] = _context_prefix_get_normal_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'];
@@ -83,6 +76,21 @@ function _context_prefix_init($method = CONTEXT_PREFIX_PATH) {
$parsed = context_prefix_parse(CONTEXT_PREFIX_DOMAIN, $q);
break;
}
+
+ // if $_GET and $_REQUEST are different, the path has NOT been
+ // aliased. We may need to rewrite the path.
+ if (in_array($method, array(CONTEXT_PREFIX_PATH, CONTEXT_PREFIX_PAIR)) && ($_GET['q'] == $_REQUEST['q'])) {
+ $q = context_prefix_unprefix($q, $method);
+ // there is nothing beyond the path prefix -- treat as frontpage
+ if ($q == '') {
+ $_GET['q'] = variable_get('site_frontpage', 'node');
+ }
+ // pass the rest of the path onto Drupal cleanly
+ 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);
@@ -109,19 +117,24 @@ function context_prefix_url_rewrite($type, $path, $original) {
// Check to see whether url rewriting has been disabled for this one
// instance -- currently only possible through cl()
if (!clswitch('get')) {
+ $active_path_prefixes = array();
+
// Retrieve the path prefixes for the current page that were
// "stripped out" and write them back into url paths.
- $active_path_prefixes = context_prefix_get(CONTEXT_PREFIX_PATH);
- if ($active_path_prefixes) {
- $parsed = context_prefix_parse(CONTEXT_PREFIX_PATH, $working_path);
+ 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);
// A "normal" url was requested -- prefix the path
- if ($type == 'alias' && !strpos($path, '://') && !count($parsed) && count($active_path_prefixes)) {
+ if (!$options['alias'] && !strpos($path, '://') && !count($parsed) && count($active_path_prefixes)) {
$args = $args + $active_path_prefixes;
}
- // Source url was requested -- remove all prefixes
- else if ($type == 'source' && count($parsed)) {
- $working_path = context_prefix_unprefix($working_path);
- }
}
}
@@ -134,8 +147,21 @@ function context_prefix_url_rewrite($type, $path, $original) {
/**
* Queries the database & modules for valid prefixes based on prefixing method.
+ *
+ * Modules that wish to provide in-code prefixes should implement the
+ * hook_context_prefix_prefixes(). Which should return an array of prefixes by
+ * by provider.
+ *
+ * For example:
+ *
+ * return array(
+ * 'my_module => array(
+ * array('prefix' => 'foo', 'id' => 1),
+ * array('prefix' => 'bar', 'id' => 2),
+ * ),
+ * );
*/
-function context_prefix_prefixes($method = CONTEXT_PREFIX_PATH) {
+function context_prefix_prefixes($requested_method = CONTEXT_PREFIX_PATH) {
static $prefixes;
if (!isset($prefixes)) {
$prefixes = array();
@@ -143,18 +169,31 @@ function context_prefix_prefixes($method = CONTEXT_PREFIX_PATH) {
// Invoke context_prefix_prefixes() and gather all prefixes
// provided "in code" (or stored by their respective modules)
foreach (module_invoke_all('context_prefix_prefixes') as $provider => $items) {
- foreach ($items as $item) {
- if ($item['prefix'] && $item['id']) {
- $method = variable_get('context_prefix_method_'. $provider, CONTEXT_PREFIX_PATH);
- $prefixes[$method][$item['prefix']] = array(
+ $method = variable_get('context_prefix_method_'. $provider, CONTEXT_PREFIX_PATH);
+
+ // If using a prefix pair we don't need to cache the valid prefixes.
+ if ($method == CONTEXT_PREFIX_PAIR) {
+ $prefix = variable_get('context_prefix_method_'. $provider .'_key', false);
+ if ($prefix != false) {
+ $prefixes[$method][$prefix] = array(
'provider' => $provider,
- 'id' => $item['id'],
+ 'id' => null,
);
}
}
+ else {
+ foreach ($items as $item) {
+ if ($item['prefix'] && $item['id']) {
+ $prefixes[$method][$item['prefix']] = array(
+ 'provider' => $provider,
+ 'id' => $item['id'],
+ );
+ }
+ }
+ }
}
- // Gather all database prefixes
+ // Gather all database prefixes.
$result = db_query("SELECT * FROM {context_prefix}");
while ($row = db_fetch_object($result)) {
$method = variable_get('context_prefix_method_'. $row->provider, CONTEXT_PREFIX_PATH);
@@ -164,7 +203,8 @@ function context_prefix_prefixes($method = CONTEXT_PREFIX_PATH) {
);
}
}
- return isset($prefixes[$method]) ? $prefixes[$method] : array();
+
+ return (isset($prefixes[$requested_method]) ? $prefixes[$requested_method] : array());
}
/**
@@ -179,12 +219,17 @@ function context_prefix_parse($method = CONTEXT_PREFIX_PATH, $q) {
// Parse the provided query string and provide an array of any prefixes found
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;
@@ -207,8 +252,8 @@ function context_prefix_parse($method = CONTEXT_PREFIX_PATH, $q) {
/**
* Removes any prefixes from a query string. For path prefixes only.
*/
-function context_prefix_unprefix($q, $providers = array()) {
- $parsed = context_prefix_parse(CONTEXT_PREFIX_PATH, $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)) {
@@ -218,12 +263,31 @@ function context_prefix_unprefix($q, $providers = array()) {
}
$parsed = array_keys($parsed);
$args = explode('/', $q);
- $args = array_diff($args, $parsed);
+ 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);
}
/**
* Invokes hook_context_prefix_provider() to gather all providers.
+ *
+ * Modules that implement hook_context_prefix_provider need to return an
+ * array of prefix definitions. Each definition should have the following
+ * keys:
+ * - name
+ * - description
+ * - callback
+ * - example
+ *
+ * See the spaces module for an usage example.
*/
function context_prefix_providers($by_method = FALSE) {
static $providers;
@@ -233,17 +297,14 @@ function context_prefix_providers($by_method = FALSE) {
}
if ($by_method) {
static $methods;
- if (!is_array($methods)) {
- $methods = array(
- CONTEXT_PREFIX_PATH => array(),
- CONTEXT_PREFIX_SUBDOMAIN => array(),
- CONTEXT_PREFIX_DOMAIN => array(),
- );
+ if (!isset($methods)) {
+ $methods = new context_prefix_cache();
+
foreach ($providers AS $id => $provider) {
- $methods[variable_get('context_prefix_method_'. $id, CONTEXT_PREFIX_PATH)][$id] = $provider;
+ $methods->add(variable_get('context_prefix_method_'. $id, CONTEXT_PREFIX_PATH), array($id => $provider));
}
}
- return $methods;
+ return $methods->get();
}
else {
return $providers;
@@ -274,16 +335,13 @@ function _context_prefix_get_normal_path($path) {
function _context_prefix_set($op = 'set', $type = CONTEXT_PREFIX_PATH, $prefix = '', $info = array()) {
static $used;
if (!$used) {
- $used = array(
- CONTEXT_PREFIX_PATH => array(),
- CONTEXT_PREFIX_SUBDOMAIN => array(),
- CONTEXT_PREFIX_DOMAIN => array(),
- );
+ $used = new context_prefix_cache();
}
switch ($op) {
case 'set':
// Store prefix for url rewriting later on in the stack
- $used[$type][] = $prefix;
+ $info['prefix'] = $prefix;
+ $used->add($type, $info, false);
// Fire the provider callback
if ($info['provider'] && $info['id']) {
@@ -297,10 +355,10 @@ function _context_prefix_set($op = 'set', $type = CONTEXT_PREFIX_PATH, $prefix =
break;
case 'get':
if ($type === 'all') {
- return $used;
+ return $used->get();
}
else {
- return $used[$type];
+ return $used->get($type);
}
}
}
@@ -335,10 +393,8 @@ function context_prefix_admin() {
// Convert $page to an array, used by other functions.
$pager_page_array = array($page);
- $methods = array(
- CONTEXT_PREFIX_PATH => t('Path prefix'),
- CONTEXT_PREFIX_DOMAIN => t('Full domain'),
- );
+ $methods = _context_ui_options();
+
$merged = array();
foreach(array_keys($methods) as $method) {
foreach(context_prefix_prefixes($method) as $prefix => $info) {
@@ -378,12 +434,7 @@ function context_prefix_settings_form() {
global $base_url;
$form = array();
- $options = array(
- CONTEXT_PREFIX_PATH => t('Path prefix'),
- CONTEXT_PREFIX_DOMAIN => t('Full domain'),
- // TODO: Implement these features
- // CONTEXT_PREFIX_SUBDOMAIN => t('Subdomain'),
- );
+ $options = _context_ui_options();
foreach (context_prefix_providers() as $id => $provider) {
// Check to see whether provider has limited the available prefixing methods
@@ -396,14 +447,26 @@ function context_prefix_settings_form() {
else {
$provider_options = $options;
}
- $form['context_prefix_method_'. $id] = array(
+
+ $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(
@@ -428,19 +491,24 @@ function theme_context_prefix_settings_form($form) {
$output = '';
$rows = array();
foreach (element_children($form) as $id) {
- if ($form[$id]['#provider']) {
+ $row = array();
+ if (isset($form[$id]['#provider'])) {
$name = $form[$id]['#title'];
$description = $form[$id]['#description'];
unset($form[$id]['#title']);
unset($form[$id]['#description']);
- $rows[] = array(
- "<strong>$name</strong><div class='description'>$description</div>",
- drupal_render($form[$id]),
- );
+ $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')), $rows);
+ $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;
}
@@ -530,19 +598,34 @@ function context_prefix_goto($provider, $prefix, $path = '', $query = NULL, $fra
* context_prefix_goto('spaces', 'mygroup'), you should end up
* at 'en/mygroup', not 'mygroup'
*/
- switch (variable_get('context_prefix_method_'. $provider, CONTEXT_PREFIX_PATH)) {
- case CONTEXT_PREFIX_PATH:
- clswitch('set', true); // Drop prefixing for context_prefix goto's
- drupal_goto($prefix .'/'. $path, $query, $fragment, $http_response_code);
- break;
- case CONTEXT_PREFIX_DOMAIN:
- $prefixes = context_prefix_prefixes(CONTEXT_PREFIX_DOMAIN);
- if (isset($prefixes[$prefix])) {
- $path = 'http://'. $prefix .'/'. $path;
- drupal_goto($path, $query, $fragment, $http_response_code);
- }
- break;
- }
+ $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); // Drop prefixing for context_prefix goto's
+ $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);
}
/**
@@ -722,3 +805,68 @@ function context_prefix_form_validate($form) {
return true;
}
}
+
+/**
+* Specialized cache for storing prefix information.
+*/
+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();
+ }
+
+ /**
+ * @param $method
+ * The method to add to the cache for
+ * @param $item
+ * Either a integer|string, or keyed array to add
+ * @param $merge
+ * Preserve keys and merge into cache for method.
+ */
+ public function add($method, $item, $merge = true) {
+ if (is_array($item) && $merge) {
+ // Need to preserve keys so we use the '+' array operator.
+ $this->cache[$method] = $this->cache[$method] + $item;
+ }
+ else {
+ $this->cache[$method][] = $item;
+ }
+ }
+
+ /**
+ * @param $method
+ * The method to retrieve from the cache for.
+ * @param $item
+ * Optionally and key of the required info.
+ *
+ * @return the desired info or false if an id doesn't exist.
+ */
+ 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;
+ }
+ }
+}
+
+/**
+ * Helper function, returns form options for prefix types.
+ */
+function _context_ui_options() {
+ return array(
+ CONTEXT_PREFIX_PATH => t('Path'),
+ CONTEXT_PREFIX_PAIR => t('Keyed pair'),
+ CONTEXT_PREFIX_DOMAIN => t('Full domain'),
+ // CONTEXT_PREFIX_SUBDOMAIN => t('Subdomain'),
+ );
+} \ No newline at end of file
diff --git a/context_prefix/context_prefix_admin.js b/context_prefix/context_prefix_admin.js
new file mode 100644
index 0000000..b225209
--- /dev/null
+++ b/context_prefix/context_prefix_admin.js
@@ -0,0 +1,30 @@
+// $Id$
+
+if (typeof(Drupal) == "undefined" || !Drupal.context_prefix_admin) {
+ Drupal.context_prefix_admin = {};
+}
+
+Drupal.context_prefix_admin.attach = function() {
+ $('select[@id^="edit-context-prefix-"]').change(function(i){
+ Drupal.context_prefix_admin.alter(this);
+ }).each(function(i){
+ Drupal.context_prefix_admin.alter(this);
+ });
+}
+
+Drupal.context_prefix_admin.alter = function(elem){
+ if (elem.value === '3') {
+ $(elem).parents('tr').find('input[@id^="edit-context-prefix-"]').show();
+ }
+ else {
+ $(elem).parents('tr').find('input[@id^="edit-context-prefix-"]').hide();
+ }
+}
+
+if (Drupal.jsEnabled) {
+ $(document).ready(function() {
+ if ($('form#context-prefix-settings-form').size() > 0) {
+ Drupal.context_prefix_admin.attach();
+ }
+ });
+}; \ No newline at end of file