View source
<?php
function spaces_load($type, $id, $reset = FALSE) {
static $spaces = array();
if (!isset($spaces[$type][$id]) || $reset) {
$spaces[$type][$id] = FALSE;
ctools_include('plugins');
$registry = spaces_types();
$info = $registry[$type];
$plugins = ctools_get_plugins('spaces', 'plugins');
if (isset($plugins[$info['plugin']]) && ($class = ctools_plugin_get_class($plugins[$info['plugin']], 'handler'))) {
$space = new $class($type, $id);
if ($space
->load()) {
$spaces[$type][$id] = $space;
}
}
}
return $spaces[$type][$id];
}
function spaces_delete($type, $id) {
return db_query("DELETE FROM {spaces_overrides} WHERE type = '%s' AND id = '%s'", $type, $id);
}
function spaces_init_space($type, $id) {
$space = spaces_load($type, $id);
if ($space) {
if ($space
->activate()) {
if ($active = spaces_get_space()) {
if ($active->type != $space->type || $active->id != $space->id) {
$active
->deactivate();
}
}
spaces_set_space($space);
}
else {
$space
->deactivate();
}
}
}
function spaces_get_space() {
return spaces_set_space();
}
function spaces_set_space($space = NULL) {
static $active_space;
if (isset($space)) {
$active_space = $space;
if ($active_space && module_exists('context') && ($plugin = context_get_plugin('condition', 'spaces_type'))) {
$plugin
->execute($space);
}
}
return isset($active_space) ? $active_space : FALSE;
}
function spaces_ctools_plugin_api($module, $api) {
if ($module == 'spaces' && $api == 'plugins') {
return array(
'version' => 3,
);
}
}
function spaces_ctools_plugin_plugins() {
return array(
'cache' => TRUE,
'use hooks' => TRUE,
);
}
function spaces_spaces_plugins() {
$plugins = array();
$plugins['space'] = array(
'handler' => array(
'path' => drupal_get_path('module', 'spaces') . '/plugins',
'file' => 'space.inc',
'class' => 'space',
),
);
$plugins['space_type'] = array(
'handler' => array(
'path' => drupal_get_path('module', 'spaces') . '/plugins',
'file' => 'space_type.inc',
'class' => 'space_type',
'parent' => 'space',
),
);
$plugins['space_type_purl'] = array(
'handler' => array(
'path' => drupal_get_path('module', 'spaces') . '/plugins',
'file' => 'space_type_purl.inc',
'class' => 'space_type_purl',
'parent' => 'space_type',
),
);
$plugins['spaces_controller'] = array(
'handler' => array(
'path' => drupal_get_path('module', 'spaces') . '/plugins',
'file' => 'spaces_controller.inc',
'class' => 'spaces_controller',
),
);
$plugins['spaces_controller_variable'] = array(
'handler' => array(
'path' => drupal_get_path('module', 'spaces') . '/plugins',
'file' => 'spaces_controller_variable.inc',
'class' => 'spaces_controller_variable',
'parent' => 'spaces_controller',
),
);
$plugins['spaces_controller_context'] = array(
'handler' => array(
'path' => drupal_get_path('module', 'spaces') . '/plugins',
'file' => 'spaces_controller_context.inc',
'class' => 'spaces_controller_context',
'parent' => 'spaces_controller',
),
);
return $plugins;
}
function spaces_spaces_registry() {
return array(
'controllers' => array(
'variable' => array(
'title' => t('Variable'),
'plugin' => 'spaces_controller_variable',
),
'context' => array(
'title' => t('Context'),
'plugin' => 'spaces_controller_context',
),
),
);
}
function spaces_types($reset = FALSE) {
return _spaces_registry('types', $reset);
}
function spaces_controllers($reset = FALSE) {
return _spaces_registry('controllers', $reset);
}
function _spaces_registry($key = NULL, $reset = FALSE) {
static $registry;
if (!isset($registry) || $reset) {
if (!$reset && ($cache = cache_get('spaces_registry', 'cache'))) {
$registry = $cache->data;
}
else {
$registry = module_invoke_all('spaces_registry');
drupal_alter('spaces_registry', $registry);
cache_set('spaces_registry', $registry);
}
}
if (isset($key)) {
return isset($registry[$key]) ? $registry[$key] : array();
}
return $registry;
}
function spaces_preset_load($name = NULL, $space_type = NULL, $reset = FALSE) {
ctools_include('export');
static $presets;
if (!isset($presets) || $reset) {
if (!$reset && ($cache = cache_get('spaces_presets', 'cache'))) {
$presets = $cache->data;
}
else {
if ($reset) {
ctools_export_load_object_reset('spaces_presets');
}
$presets = ctools_export_load_object('spaces_presets', 'all');
cache_set('spaces_presets', $presets);
}
}
if (!isset($name) && !isset($space_type)) {
return $presets;
}
if (isset($name)) {
return isset($presets[$name]) ? $presets[$name] : FALSE;
}
if (isset($space_type)) {
$return = array();
foreach ($presets as $key => $preset) {
if ($preset->space_type === $space_type) {
$return[$key] = $preset;
}
}
return $return;
}
}
function spaces_preset_save($preset) {
$existing = spaces_preset_load($preset->name, NULL, TRUE);
if ($existing && $existing->export_type & EXPORT_IN_DATABASE) {
drupal_write_record('spaces_presets', $preset, 'name');
}
else {
drupal_write_record('spaces_presets', $preset);
}
spaces_preset_load(NULL, NULL, TRUE);
return TRUE;
}
function spaces_preset_save_from_space($preset, $space) {
$space
->activate();
foreach (array_keys(spaces_controllers()) as $controller) {
$preset->value[$controller] = array_merge($space->controllers->{$controller}
->get(NULL, 'preset'), $space->controllers->{$controller}
->get(NULL, 'space'));
}
spaces_preset_save($preset);
}
function spaces_preset_delete($preset) {
if (isset($preset->name) && $preset->export_type & EXPORT_IN_DATABASE) {
db_query("DELETE FROM {spaces_presets} WHERE name = '%s'", $preset->name);
spaces_preset_load(NULL, NULL, TRUE);
return TRUE;
}
return FALSE;
}
function spaces_preset_export($object, $indent = '') {
$output = ctools_export_object('spaces_presets', $object, $indent);
$translatables = array();
foreach (array(
'title',
'description',
) as $key) {
if (!empty($object->{$key})) {
$translatables[] = $object->{$key};
}
}
$translatables = array_filter(array_unique($translatables));
if (!empty($translatables)) {
$output .= "\n";
$output .= "{$indent}// Translatables\n";
$output .= "{$indent}// Included for use with string extractors like potx.\n";
sort($translatables);
foreach ($translatables as $string) {
$output .= "{$indent}t(" . ctools_var_export($string) . ");\n";
}
}
return $output;
}
function spaces_ahah_check() {
if (!empty($_POST) && isset($_POST['form_build_id'])) {
if ($form = form_get_cache($_POST['form_build_id'], $form_state)) {
if (isset($form['#space'])) {
list($type, $id) = explode(':', $form['#space']['#value']);
spaces_init_space($type, $id);
}
}
}
}
function spaces_router($op, $object = NULL) {
static $router;
if (!isset($router)) {
$router = array();
if ($space = spaces_get_space()) {
$router[$space->type] = $space;
}
ctools_include('plugins');
$plugins = ctools_get_plugins('spaces', 'plugins');
foreach (spaces_types() as $type => $info) {
if (!isset($router[$type]) && isset($plugins[$info['plugin']]) && ($class = ctools_plugin_get_class($plugins[$info['plugin']], 'handler'))) {
$router[$type] = new $class($type);
}
}
}
foreach ($router as $space) {
$space
->router($op, $object);
}
}
function spaces_features($type = NULL, $reset = FALSE) {
static $features;
static $by_type;
if (!isset($features) || $reset) {
$features = array();
$by_type = array();
$types = array_merge(array_keys(spaces_types()), array(
'site',
));
foreach (features_get_features() as $feature) {
if (module_exists($feature->name) && !empty($feature->info['spaces']['types'])) {
$features[$feature->name] = $feature;
$feature->info['spaces']['types'] = is_array($feature->info['spaces']['types']) ? $feature->info['spaces']['types'] : array(
$feature->info['spaces']['types'],
);
foreach ($feature->info['spaces']['types'] as $enabled_type) {
if ($enabled_type === 'all') {
foreach ($types as $t) {
$by_type[$t][$feature->name] = $feature;
}
}
elseif (in_array($enabled_type, $types, TRUE)) {
$by_type[$enabled_type][$feature->name] = $feature;
}
else {
$by_type['site'][$feature->name] = $feature;
}
}
}
}
}
if (isset($type)) {
return !empty($by_type[$type]) ? $by_type[$type] : array();
}
return $features;
}
function spaces_access_space($account = NULL) {
$space = spaces_get_space();
return $space ? $space
->access_space($account) : TRUE;
}
function spaces_access_admin($account = NULL, $space = NULL) {
$space = isset($space) ? $space : spaces_get_space();
if ($space) {
return $space
->access_admin($account);
}
return user_access('administer site configuration', $account);
}
function spaces_access_admin_perms($perms = array(), $account = NULL, $space = NULL) {
$perm_access = TRUE;
if (!empty($perms)) {
foreach ($perms as $perm) {
$perm_access = $perm_access && user_access($perm, $account);
}
}
return $perm_access ? spaces_access_admin($account, $space) : FALSE;
}
function spaces_access_feature($op = 'view', $feature, $account = NULL, $space = NULL, $reset = FALSE) {
static $cache;
$space = isset($space) ? $space : spaces_get_space();
$cid = $op . ':' . $feature . ':' . (isset($account) ? $account->uid : 'CURRENT_USER') . ':' . (!empty($space) ? "{$space->type}-{$space->id}" : "SITE_SPACE");
if (!isset($cache) || $reset) {
$cache = array();
}
if (!isset($cache[$cid])) {
$features = spaces_features();
if (!isset($features[$feature]) || arg(0) === 'admin') {
$cache[$cid] = TRUE;
}
elseif ($space) {
$cache[$cid] = $space
->access_feature($op, $feature, $account);
}
else {
$features = variable_get('spaces_features', array());
$cache[$cid] = user_access('access content', $account) && !empty($features[$feature]);
}
}
return $cache[$cid];
}
function spaces_access_feature_perms($op = 'view', $feature, $account = NULL, $space = NULL, $perms = array()) {
$access = spaces_access_feature($op, $feature, $account, $space);
if (!empty($perms)) {
foreach ($perms as $perm) {
$access = $access && user_access($perm);
}
}
return $access;
}
function spaces_access_user($op = 'view', $account = NULL) {
$space = spaces_get_space();
return $space ? $space
->access_user($op, $account) : TRUE;
}
function spaces_help($path, $arg) {
switch ($path) {
case 'admin/help#spaces':
$output = file_get_contents(drupal_get_path('module', 'spaces') . '/README.txt');
return module_exists('markdown') ? filter_xss_admin(module_invoke('markdown', 'filter', 'process', 0, -1, $output)) : '<pre>' . check_plain($output) . '</pre>';
}
}
function spaces_menu() {
$items = array();
$items['spaces-access-denied'] = array(
'access callback' => FALSE,
'type' => MENU_CALLBACK,
);
$items['spaces-frontpage'] = array(
'page callback' => 'spaces_frontpage',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['features'] = array(
'title' => 'Features',
'description' => 'Configure features for this space.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'spaces_features_form',
),
'access callback' => 'spaces_access_admin',
'access arguments' => array(),
'type' => MENU_NORMAL_ITEM,
'file' => 'spaces.admin.inc',
);
return $items;
}
function spaces_menu_alter(&$items) {
$router_items = array(
'node/%node',
'node/%node/edit',
'user/%user/view',
'user/%user_uid_optional',
'user/%user_category/edit',
);
foreach (node_get_types('types', NULL, TRUE) as $type) {
$type_url_str = str_replace('_', '-', $type->type);
$router_items[] = 'node/add/' . $type_url_str;
}
foreach ($router_items as $path) {
if (isset($items[$path])) {
$arguments = isset($items[$path]['access arguments']) ? $items[$path]['access arguments'] : array();
$arguments[] = isset($items[$path]['access callback']) ? $items[$path]['access callback'] : NULL;
$items[$path]['access callback'] = 'spaces_menu_access';
$items[$path]['access arguments'] = $arguments;
}
}
$graft = array();
$graft['features'] = $items['features'];
foreach ($items as $path => $item) {
if (strpos($path, 'features/') === 0) {
$graft[$path] = $item;
}
}
foreach (spaces_types() as $type => $info) {
if (isset($info['path'])) {
$graft['features']['type'] = MENU_LOCAL_TASK;
$graft['features']['access callback'] = 'spaces_access_admin';
$graft['features']['access arguments'] = array();
$argcount = count(explode('/', $info['path']));
foreach ($graft as $path => $item) {
$newitem = $item;
foreach (array(
'page arguments',
'access arguments',
'title arguments',
) as $key) {
if (!empty($newitem[$key])) {
foreach ($newitem[$key] as $position => $argument) {
if (is_numeric($argument)) {
$newitem[$key][$position] = $newitem[$key][$position] + $argcount;
}
}
}
}
$items["{$info['path']}/{$path}"] = $newitem;
}
$items["{$info['path']}/features/configure"] = array(
'title' => 'Configure',
'description' => 'Configure features for this space.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'spaces_features_form',
),
'access callback' => 'spaces_access_admin',
'access arguments' => array(),
'type' => MENU_DEFAULT_LOCAL_TASK,
'file' => 'spaces.admin.inc',
);
$items["{$info['path']}/features/overrides"] = array(
'title' => 'Overrides',
'description' => 'Manage override values for this space.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'spaces_overrides_form',
),
'access callback' => 'spaces_access_admin_perms',
'access arguments' => array(
array(
'administer spaces',
),
),
'type' => MENU_LOCAL_TASK,
'file' => 'spaces.admin.inc',
'module' => 'spaces',
);
}
}
if (module_exists('views') && isset($items['user/autocomplete'])) {
$items['user/autocomplete']['page callback'] = 'spaces_user_autocomplete';
$items['user/autocomplete']['module'] = 'spaces';
$items['user/autocomplete']['file'] = 'spaces.admin.inc';
}
}
function spaces_menu_access() {
$args = func_get_args();
$access_callback = array_pop($args);
if (empty($access_callback) || call_user_func_array($access_callback, $args)) {
$map = features_get_component_map('node');
if ($access_callback == 'node_access' && $args[0] == 'create') {
$node_type = str_replace('-', '_', $args[1]);
$feature = !empty($map[$node_type]) ? reset($map[$node_type]) : NULL;
if ($feature) {
return spaces_access_feature('create', $feature);
}
}
else {
foreach (array_filter($args, 'is_object') as $object) {
$type = isset($object->nid) ? 'node' : (isset($object->uid) ? 'user' : NULL);
if ($type && spaces_is_spaces_object($type, $object)) {
if ($type == 'node') {
$feature = !empty($map[$object->type]) ? reset($map[$object->type]) : NULL;
if ($feature) {
return spaces_access_feature('view', $feature);
}
}
elseif ($type == 'user') {
return spaces_access_user('view', $object);
}
break;
}
}
}
return TRUE;
}
return FALSE;
}
function spaces_frontpage() {
$space = spaces_get_space();
if ($space) {
$types = spaces_types();
$type_info = $types[$space->type];
if (isset($type_info['path'])) {
$path = preg_replace('/%(|[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)$/', $space->id, $type_info['path']);
menu_set_active_item($path);
return menu_execute_active_handler();
}
}
drupal_not_found();
exit;
}
function spaces_theme() {
$items = array();
$base = array(
'arguments' => array(
'form' => array(),
),
'file' => 'spaces.theme.inc',
'path' => drupal_get_path('module', 'spaces'),
);
$items['spaces_features_form'] = $items['spaces_preset_form'] = $items['spaces_overrides_form'] = $base;
return $items;
}
function spaces_views_api() {
return array(
'api' => 2,
'path' => drupal_get_path('module', 'spaces') . '/includes',
);
}
function spaces_perm() {
return array(
'administer spaces',
);
}
function spaces_init() {
spaces_ahah_check();
if (module_exists('spaces_customtext')) {
global $language;
$language->language = $language->language === 'spaces_customtext' ? spaces_customtext_cache() : $language->language;
}
if (variable_get('menu_rebuild_needed', FALSE) || !variable_get('menu_masks', array())) {
menu_rebuild();
}
if ($object = menu_get_object()) {
$type = 'node';
}
elseif (($item = menu_get_item()) && isset($item['map'])) {
foreach (array_filter($item['map'], 'is_object') as $object) {
$type = isset($object->nid) ? 'node' : (isset($object->uid) ? 'user' : NULL);
break;
}
}
if (isset($type) && !spaces_is_spaces_object($type, $object)) {
spaces_router($type, $object);
}
if (!spaces_access_space()) {
menu_set_active_item('spaces-access-denied');
}
spaces_router('init');
}
function spaces_flush_caches() {
cache_clear_all('spaces_map', 'cache', TRUE);
cache_clear_all('spaces_presets', 'cache', TRUE);
cache_clear_all('spaces_registry', 'cache', TRUE);
}
function spaces_block($op, $delta = 0) {
if (module_exists('jquery_ui')) {
if ($op == 'list') {
return array(
'menu_editor' => array(
'info' => t('Reorder menu'),
'admin' => TRUE,
),
);
}
elseif ($op == 'view' && $delta == 'menu_editor') {
if (spaces_access_admin()) {
$space = spaces_get_space();
if ($space && $space->type == 'user') {
return array();
}
return array(
'subject' => t('Reorder menu'),
'content' => drupal_get_form('spaces_get_menu_editor'),
);
}
}
}
}
function spaces_get_menu_editor(&$form_state) {
jquery_ui_add(array(
'ui.draggable',
'ui.droppable',
'ui.sortable',
));
drupal_add_js(drupal_get_path('module', 'context_ui') . '/json2.js');
drupal_add_js(drupal_get_path('module', 'context_ui') . '/jquery.pageEditor.js');
drupal_add_js(drupal_get_path('module', 'spaces') . '/spaces.js');
drupal_add_css(drupal_get_path('module', 'spaces') . '/spaces.css');
$form = system_settings_form(array());
unset($form['#theme']);
$form['#attributes'] = array(
'class' => 'spaces-menu-editor',
);
$form['space_menu_items'] = array(
'#type' => 'hidden',
'#element_validate' => array(
'spaces_menu_items_validate',
),
);
$form['buttons']['edit'] = array(
'#submit' => array(),
'#type' => 'submit',
'#value' => t('Edit'),
'#attributes' => array(
'class' => 'spaces-menu-editor',
),
);
$form['buttons']['reset']['#access'] = FALSE;
$form['buttons']['submit']['#value'] = t('Save');
$form['buttons']['submit']['#attributes'] = array(
'class' => 'spaces-menu-save',
'style' => 'display: none;',
);
$form['buttons']['cancel'] = array(
'#submit' => array(),
'#value' => t('Cancel'),
'#type' => 'button',
'#attributes' => array(
'class' => 'spaces-menu-cancel',
'style' => 'display: none;',
),
);
return $form;
}
function spaces_menu_items_validate($element, &$form_state) {
$base_path = base_path();
$items = array();
$weight = -20;
if (!empty($form_state['values']['space_menu_items'])) {
foreach (spaces_json_decode($form_state['values']['space_menu_items']) as $i) {
if (strpos($i, $base_path) === 0) {
$path = substr($i, strlen($base_path));
$path = array_shift(explode('#', $path));
$path = drupal_get_normal_path($path);
$items[$path] = $weight;
$weight++;
}
}
}
if (empty($items)) {
form_set_error('space_menu_items', t('Invalid submission'));
}
else {
$form_state['values']['space_menu_items'] = $items;
}
unset($form_state['values']['edit']);
unset($form_state['values']['cancel']);
}
function spaces_features_order_menu(&$links) {
$weights = variable_get('space_menu_items', array());
$first = TRUE;
foreach ($links as $k => $v) {
if ($first) {
$first = FALSE;
if (isset($links[$k]['attributes']['class'])) {
$links[$k]['attributes']['class'] .= ' spaces-menu-editable';
}
else {
$links[$k]['attributes']['class'] = 'spaces-menu-editable';
}
}
if (isset($weights[$v['href']])) {
$links[$k]['#weight'] = $weights[$v['href']];
}
}
if (!empty($weights)) {
uasort($links, 'element_sort');
}
}
function spaces_preprocess_page(&$vars) {
spaces_features_order_menu($vars['primary_links']);
}
function spaces_json_decode($json, $assoc = FALSE) {
if (function_exists('json_decode')) {
return json_decode($json, $assoc);
}
return _spaces_json_decode($json);
}
function _spaces_json_decode($json) {
$comment = false;
$out = '$x = ';
for ($i = 0; $i < strlen($json); $i++) {
if (!$comment) {
switch ($json[$i]) {
case '{':
$out .= ' (object) array(';
break;
case '}':
$out .= ')';
break;
case '[':
$out .= ' array(';
break;
case ']':
$out .= ')';
break;
case ':':
$out .= '=>';
break;
default:
$out .= $json[$i];
break;
}
}
else {
$out .= $json[$i];
}
if ($json[$i] == '"') {
$comment = !$comment;
}
}
eval($out . ';');
return $x;
}
function spaces_get_space_from_object($type, $object) {
static $spaces;
$id = $type == 'node' ? $object->nid : $object->uid;
if (!isset($spaces[$type][$id])) {
$spaces = module_invoke_all('spaces_get_space_from_object', $type, $object);
if ($space = current($spaces)) {
$spaces[$type][$id] = array(
'type' => $space->type,
'id' => $space->id,
);
}
else {
$spaces[$type][$id] = FALSE;
}
}
return $spaces[$type][$id] ? spaces_load($spaces[$type][$id]['type'], $spaces[$type][$id]['id']) : FALSE;
}
function spaces_is_spaces_object($type, $object) {
if ($object_space = spaces_get_space_from_object($type, $object)) {
if ($current_space = spaces_get_space()) {
return $object_space->id == $current_space->id && $object_space->type == $current_space->type;
}
else {
return FALSE;
}
}
return TRUE;
}