summaryrefslogtreecommitdiffstats
path: root/context_prefix
diff options
context:
space:
mode:
authorJeff Miccolis2008-04-08 20:48:35 (GMT)
committerJeff Miccolis2008-04-08 20:48:35 (GMT)
commit13588deeb463a860541f56e6ac7fc3af1342ea04 (patch)
treeee675bfffdd38f22ec796bc17635e156036ce42a /context_prefix
parent509748535cf535e96462983071e7c60eb7a7d167 (diff)
Moved context_prefix into it's own directory
Diffstat (limited to 'context_prefix')
-rw-r--r--context_prefix/context_prefix.info5
-rw-r--r--context_prefix/context_prefix.install48
-rw-r--r--context_prefix/context_prefix.module330
3 files changed, 383 insertions, 0 deletions
diff --git a/context_prefix/context_prefix.info b/context_prefix/context_prefix.info
new file mode 100644
index 0000000..80ac00a
--- /dev/null
+++ b/context_prefix/context_prefix.info
@@ -0,0 +1,5 @@
+; $Id$
+name = Context Prefix
+description = "Provides generalized context prefixing"
+dependencies = context
+package = Context \ No newline at end of file
diff --git a/context_prefix/context_prefix.install b/context_prefix/context_prefix.install
new file mode 100644
index 0000000..8070c9e
--- /dev/null
+++ b/context_prefix/context_prefix.install
@@ -0,0 +1,48 @@
+<?php
+// $Id$
+
+function context_prefix_install() {
+ switch ($GLOBALS['db_type']) {
+ case 'mysqli':
+ case 'mysql':
+ db_query("CREATE TABLE {context_prefix} (module VARCHAR(255) NOT NULL, prefix VARCHAR(255) NOT NULL, id INT(10) NOT NULL, PRIMARY KEY (prefix))");
+ db_query("UPDATE {system} SET weight = -20 WHERE name = 'context_prefix'");
+ break;
+ }
+}
+
+function context_prefix_update_1() {
+ $items = array();
+ $items[] = update_sql("UPDATE {system} SET weight = -20 WHERE name = 'context_prefix'");
+ return $items;
+}
+
+function context_prefix_update_2() {
+ $items = array();
+ $items[] = update_sql("CREATE TABLE {context_prefix} (space VARCHAR(255) NOT NULL, path VARCHAR(255) NOT NULL, id INT(10) NOT NULL, PRIMARY KEY (path))");
+ $paths = variable_get('context_paths', array());
+ if ($paths) {
+ foreach ($paths as $space => $p) {
+ foreach ($p as $path => $nid) {
+ db_query("REPLACE INTO {context_prefix} (space, path, id) VALUES('%s', '%s', %d)", $space, $path, $nid);
+ }
+ }
+ variable_del('context_paths');
+ }
+ return $items;
+}
+
+function context_prefix_update_3() {
+ $items = array();
+ $items[] = update_sql("ALTER TABLE {context_prefix} CHANGE COLUMN space space VARCHAR(255) NOT NULL;");
+ $items[] = update_sql("ALTER TABLE {context_prefix} CHANGE COLUMN path path VARCHAR(255) NOT NULL;");
+ $items[] = update_sql("ALTER TABLE {context_prefix} CHANGE COLUMN id id VARCHAR(255) NOT NULL;");
+ return $items;
+}
+
+function context_prefix_update_4() {
+ $items = array();
+ $items[] = update_sql("ALTER TABLE {context_prefix} CHANGE COLUMN space module VARCHAR(255) NOT NULL;");
+ $items[] = update_sql("ALTER TABLE {context_prefix} CHANGE COLUMN path prefix VARCHAR(255) NOT NULL;");
+ return $items;
+} \ No newline at end of file
diff --git a/context_prefix/context_prefix.module b/context_prefix/context_prefix.module
new file mode 100644
index 0000000..f819133
--- /dev/null
+++ b/context_prefix/context_prefix.module
@@ -0,0 +1,330 @@
+<?php
+// $Id$
+
+/**
+ * hook_menu()
+ */
+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 Prefixes'),
+ 'description' => t('Displays a list of context definitions.'),
+ 'path' => 'admin/build/context/prefix',
+ 'callback' => 'context_prefix_admin',
+ 'access' => user_access('administer site configuration'),
+ 'weight' => 10,
+ );
+ }
+ return $items;
+}
+
+/**
+ * hook_init()
+ * Checks for any valid context prefixes in request string and sets the context appropriately
+ */
+function context_prefix_init() {
+ $q = isset($_REQUEST["q"]) ? trim($_REQUEST["q"], "/") : '';
+ $prefix = _context_prefix_get_prefix($q);
+ $items = context_prefix_items();
+ if (isset($items[$prefix]) && $active = $items[$prefix] ) {
+ context_set('context_prefix', $active->module, $active->id);
+ context_set('context_prefix', 'prefix', $prefix);
+ // if $_GET and $_REQUEST are different, the path has been aliased
+ // we will continue to the aliased destination
+ if ($_GET['q'] != $_REQUEST['q']) {
+ return;
+ }
+ // there is nothing beyond the path prefix -- treat as frontpage
+ else if ($q == $prefix) {
+ $_GET['q'] = variable_get('site_frontpage', 'node');
+ }
+ // pass the rest of the path onto Drupal cleanly
+ else {
+ // for now, we check arg(0) + arg(1) for the prefix
+ if (strpos($q, $prefix) !== 0) {
+ $q = explode('/', $q);
+ if ($q[1] == $prefix) {
+ unset($q[1]);
+ }
+ $q = implode('/', $q);
+ // reset _REQUEST as other prefixing modules (i18n) will use it and not $_GET
+ $_REQUEST['q'] = $_GET['q'] = $q;
+ }
+ // trim off context path and reset q
+ else {
+ $q = trim(substr($q, strlen($prefix)), '/');
+ $_REQUEST['q'] = $_GET['q'] = _context_prefix_get_normal_path($q, $prefix);
+ }
+ }
+ }
+}
+
+/**
+ * Page callback for the context_prefix administration page.
+ */
+function context_prefix_admin() {
+ $items = context_prefix_items();
+ if ($items) {
+ $rows = array();
+ foreach ($items as $item) {
+ $rows[] = array($item->module, $item->prefix, $item->id);
+ }
+ return theme('table', array(t('Module'), t('Prefix'), t('ID')), $rows);
+ }
+ return "<p>". t('No context prefix definitions found.') ."</p>";
+}
+
+/**
+ * Provides a simple API for validating, adding, and deleting context defintions.
+ */
+function context_prefix_api($op = 'insert', $context) {
+ switch ($op) {
+ case 'validate':
+ if (check_plain($context['module']) && preg_match('!^[a-z0-9_-]+$!', $context['prefix'])) {
+ $id = db_result(db_query("SELECT id FROM {context_prefix} WHERE prefix = '%s'", $context['prefix']));
+ return $id ? false : true;
+ }
+ else {
+ return false;
+ }
+ case 'insert':
+ if (context_prefix_api('validate', $context)) {
+ $status = db_query("INSERT INTO {context_prefix} (module, prefix, id) VALUES ('%s', '%s', %d)", $context['module'], $context['prefix'], $context['id']);
+ return $status;
+ }
+ return false;
+ 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 module = '%s' AND $param = '%s'", $context['module'], $where));
+ if ($check) {
+ $status = db_query("DELETE FROM {context_prefix} WHERE module = '%s' AND $param = '%s'", $context['module'], $where);
+ return $status;
+ }
+ return false;
+ }
+ return false;
+}
+
+/**
+ * Returns an array of available context definitions. If provided an
+ * optional module argument, will only provide definitions for the
+ * specified module.
+ */
+function context_prefix_items($module = NULL) {
+ static $items;
+ static $by_module;
+ if (!$items) {
+ $items = $by_module = array();
+ $result = db_query("SELECT * FROM {context_prefix} ORDER BY module ASC");
+ while ($item = db_fetch_object($result)) {
+ $items[$item->prefix] = $item;
+ $by_module[$item->module][$item->prefix] = $item;
+ }
+ }
+ if ($module) {
+ return isset($by_module[$module]) ? $by_module[$module] : array();
+ }
+ else {
+ return $items;
+ }
+}
+
+/**
+ * Returns a prefix string from a url if a valid one is found
+ */
+function _context_prefix_get_prefix($q) {
+ $exploded_q = explode('/', $q);
+ $prefix = array_shift($exploded_q);
+ // skip over i18n prefix if found
+ if (module_exists('i18n') && function_exists('locale_supported_languages')) {
+ $languages = locale_supported_languages();
+ $languages = array_keys($languages['name']); // grab only language prefixes
+ // if first prefix is in languages array, throw it out and use 2nd prefix
+ if (array_search($path, $languages) !== false) {
+ $prefix = array_shift($exploded_q);
+ }
+ }
+ // check that this prefix is valid
+ $valid = context_prefix_items();
+ if (isset($valid[$prefix])) {
+ return $prefix;
+ }
+ else {
+ return false;
+ }
+}
+
+/**
+ * Taken from i18n
+ */
+function _context_prefix_get_normal_path($path, $prefix) {
+ // If bootstrap, drupal_lookup_path is not defined
+ if (!function_exists('drupal_get_headers')) {
+ return $path;
+ }
+ // Check alias without lang
+ elseif ($alias = drupal_lookup_path('source', $path)) {
+ return $alias;
+ }
+ else {
+ return $path;
+ }
+}
+
+/**
+ * Jose's very smart collision avoidance
+ */
+if (!function_exists('custom_url_rewrite')) {
+ function custom_url_rewrite($type, $path, $original) {
+ return context_prefix_url_rewrite($type, $path, $original);
+ }
+}
+
+/**
+ * Rewrites path with current context and removes context if searching for source path
+ */
+function context_prefix_url_rewrite($type, $path, $original) {
+ $working_path = $path; // preserve original path
+
+ if (module_exists('i18n')) {
+ if ($type == 'alias' && !i18n_get_lang_prefix($path)) {
+ $prefix[] = i18n_get_lang();
+ }
+ elseif ($type == 'source') {
+ if ($path == $original) {
+ $working_path = i18n_get_normal_path($working_path);
+ }
+ else { // Path may have been dealiased but still have language prefix
+ $working_path = i18n_get_lang_prefix($working_path, TRUE);
+ }
+ }
+ }
+
+ // by now i18n has added/removed language prefix as needed
+ if (!clswitch('get')) {
+ $context = context_get('context_prefix', 'prefix');
+ if ($type == 'alias' && !_context_prefix_get_prefix($working_path) && $context) {
+ $prefix[] = $context;
+ }
+ else if ($type == 'source') {
+ if (_context_prefix_get_prefix($working_path)) {
+ $working_path = trim(substr($working_path, strlen($context)), '/');
+ }
+ }
+ }
+
+ if ($working_path) {
+ $prefix[] = $working_path;
+ }
+
+ return $prefix ? implode('/', $prefix) : '';
+}
+
+/**
+ * Custom l wrapper for links that need to leave all group contexts
+ */
+function cl($text, $path, $attributes = array(), $query = NULL, $fragment = NULL, $absolute = FALSE, $html = FALSE, $dropcontext = FALSE) {
+ clswitch('set', $dropcontext);
+ if (!$dropcontext && $path == '<front>') {
+ $path = context_prefix_url_rewrite('alias', '', '');
+ }
+ $l = l($text, $path, $attributes, $query, $fragment, $absolute, $html);
+ clswitch('reset');
+ return $l;
+}
+
+/**
+ * Returns whether the current l/url call should use context rewriting or not
+ */
+function clswitch($op, $absolute = null) {
+ static $drop;
+ switch ($op) {
+ case 'set';
+ $drop = $absolute;
+ break;
+ case 'get':
+ return $drop;
+ break;
+ case 'reset':
+ $drop = null;
+ break;
+ }
+}
+
+/**
+ * Like theme_links, but handles context warping.
+ * theme_links couldn't believe it.
+ */
+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 = '';
+
+ // Automatically add a class to each link and also to each LI
+ if (isset($link['attributes']) && isset($link['attributes']['class'])) {
+ $link['attributes']['class'] .= ' '. $key;
+ $class = $key;
+ }
+ else {
+ $link['attributes']['class'] = $key;
+ $class = $key;
+ }
+
+ // Add first and last classes to the list of links to help out themers.
+ $extra_class = '';
+ if ($i == 1) {
+ $extra_class .= 'first ';
+ }
+ if ($i == $num_links) {
+ $extra_class .= 'last ';
+ }
+ $output .= '<li class="'. $extra_class . $class .'">';
+
+ // Is the title HTML?
+ $html = isset($link['html']) && $link['html'];
+
+ // Initialize fragment and query variables.
+ $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']) {
+ //Some links are actually not links, but we wrap these in <span> for adding title and class attributes
+ 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;
+} \ No newline at end of file