Commit 50974853 authored by young hahn's avatar young hahn

Adding context_prefix, a module that allows other modules to register url...

Adding context_prefix, a module that allows other modules to register url prefixes for setting a context
parent bed88bb2
; $Id$
name = Context Prefix
description = "Provides generalized context prefixing"
dependencies = context
package = Context
\ No newline at end of file
<?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
<?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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment