skinr_context.module in Skinr 7.2
Same filename and directory in other branches
Provides Skinr integration with Context.
File
skinr_context/skinr_context.moduleView source
<?php
/**
* Implements hook_hook_info().
*/
function skinr_context_hook_info() {
$hooks['skinr_context_group_defaults'] = array(
'group' => 'skinr_default',
);
return $hooks;
}
/**
* Implements hook_module_implements_alter().
*/
function skinr_context_module_implements_alter(&$implementations, $hook) {
if ($hook == 'modules_enabled') {
// Make our version of hook_modules_enabled() happen before that of
// skinr core. This way skin settings groups are imported before skin
// configurations.
$group = $implementations['skinr_context'];
unset($implementations['skinr_context']);
$implementations = array_reverse($implementations, TRUE);
$implementations['skinr_context'] = $group;
$implementations = array_reverse($implementations, TRUE);
}
}
/**
* @file
* Provides Skinr integration with Context.
*/
/**
* Validate a skin group object.
*
* @param $group
* A skin group object.
*
* @return
* TRUE on success, FALSE on failure.
*/
function skinr_context_group_validate(&$group) {
if (empty($group->gid) || empty($group->module) || empty($group->element) || empty($group->title)) {
return FALSE;
}
if (!isset($group->conditions) || !is_array($group->conditions)) {
return FALSE;
}
return TRUE;
}
/**
* Save a skin group object.
*
* @param $group
* A skin settings group object.
*
* @return
* TRUE on success, FALSE on failure.
*/
function skinr_context_group_save(&$group) {
// Make sure we're getting valid data.
if (!skinr_context_group_validate($group)) {
return FALSE;
}
// Load the stored skin settings group object, if any.
if (!isset($group->original)) {
// Load an uncached version of the skin settings object.
if (!($group->original = skinr_context_group_load_unchanged($group->gid))) {
unset($group->original);
}
}
// Let modules modify the node before it is saved to the database.
module_invoke_all('skinr_context_group_presave', $group);
// Clear the static loading cache. We do it ahead of saving to ensure
// skinr_context_skinr_skin_presave(), invoked through skinr_skin_save(),
// loads an updated $group.
// @todo Once we have a more granular reset for skinr_skin_load_multiple(), we
// need to use it here.
drupal_static_reset('skinr_context_group_load_multiple');
// Clear context's cache.
context_invalidate_cache();
if (!empty($group->original)) {
// Record exists, so let's update.
$status = drupal_write_record('skinr_groups', $group, 'gid');
// When status changes, update status of linked skin settings.
if ($group->status != $group->original->status) {
$params = array(
'gid' => $group->gid,
'status' => $group->status ? 0 : 1,
);
// Update status of linked skin configurations.
$sids = skinr_context_group_get_sids($params);
foreach ($sids as $sid) {
$skin = skinr_skin_load_unchanged($sid);
$skin->original = clone $skin;
$skin->status = $group->status;
skinr_skin_save($skin);
}
}
module_invoke_all('skinr_context_group_update', $group);
}
else {
// Insert a new record.
$status = drupal_write_record('skinr_groups', $group);
module_invoke_all('skinr_context_group_insert', $group);
}
// Clear internal properties.
unset($group->original);
return $status;
}
/**
* Delete a skin group object.
*
* @param $gid
* The skin settings group ID.
*/
function skinr_context_group_delete($gid) {
skinr_context_group_delete_multiple(array(
$gid,
));
}
/**
* Delete multiple skin settings group objects.
*
* @param $gids
* An array of skin settings group IDs.
*/
function skinr_context_group_delete_multiple($gids) {
$transaction = db_transaction();
if (!empty($gids)) {
$groups = skinr_context_group_load_multiple($gids);
try {
foreach ($groups as $gid => $group) {
module_invoke_all('skinr_context_group_delete', $group);
// Delete all skin settings associated with this group.
$params = array(
'gid' => $gid,
);
$sids = skinr_context_group_get_sids($params);
skinr_skin_delete_multiple($sids);
}
// Delete after calling hooks so that they can query node tables as needed.
db_delete('skinr_groups')
->condition('gid', $gids, 'IN')
->execute();
} catch (Exception $e) {
$transaction
->rollback();
watchdog_exception('skinr', $e);
throw $e;
}
// Clear the skinr_context_group_load_multiple cache.
drupal_static_reset('skinr_context_group_load_multiple');
// Clear context's cache.
context_invalidate_cache();
}
}
/**
* Load a skin settings group object from the database.
*
* @param $gid
* The skin settings group ID.
*
* @return
* A fully-populated skin settings group object.
*/
function skinr_context_group_load($gid = NULL) {
$gids = isset($gid) ? array(
$gid,
) : array();
$group = skinr_context_group_load_multiple($gids);
return $group ? reset($group) : FALSE;
}
/**
* Load skin settings group objects from the database.
*
* This function should be used whenever you need to load more than one skin
* configuration group from the database. Skin settings groups are loaded
* into memory and will not require database access if loaded again during the
* same page request.
*
* @see skinr_context_group_get_gids()
*
* @param $gids
* An array of skin settings group IDs.
*
* @return
* An array of skin settings group objects indexed by gid.
*/
function skinr_context_group_load_multiple($gids = array()) {
// @todo Do we want to write a more granular cache reset?
$groups =& drupal_static(__FUNCTION__, array());
// Create a new variable which is either a prepared version of the $gids
// array for later comparison with cached skin group objects, or FALSE
// if no $gids were passed. The $gids array is reduced as items are loaded
// from cache, and we need to know if it's empty for this reason to avoid
// querying the database when all requested skin group objects are
// loaded from cache.
$passed_gids = !empty($gids) ? array_flip($gids) : FALSE;
if ($passed_gids) {
$gids = array_keys(array_diff_key($passed_gids, $groups));
}
// Load any remaining skin groups from the database. This is the
// case if $gids is set to FALSE (so we load all groups), or if there are any
// gids left to load.
if ($gids === FALSE || $gids) {
// Build the query.
$query = db_select('skinr_groups', 'g')
->fields('g', array(
'gid',
'module',
'element',
'title',
'description',
'conditions',
'condition_mode',
'weight',
'status',
));
if ($gids !== FALSE) {
$query
->condition('gid', $gids);
}
$queried_groups = $query
->execute()
->fetchAllAssoc('gid');
foreach ($queried_groups as $gid => $group) {
// Unserialize options array.
$queried_groups[$gid]->conditions = unserialize($group->conditions);
// Let modules modify the skin settings group.
module_invoke_all('skinr_context_group_load', $queried_groups[$gid]);
}
$groups += $queried_groups;
}
// Ensure that the returned array is ordered the same as the original
// $gids array if this was passed in and remove any invalid gids.
if ($passed_gids) {
// Remove any invalid gids from the array.
$passed_gids = array_intersect_key($passed_gids, $groups);
$return = array();
foreach ($passed_gids as $gid => $ignore) {
$return[$gid] = $groups[$gid];
}
}
else {
$return = $groups;
}
return $return;
}
/**
* Load an uncached version of a skin settings group object.
*
* @param $gid
* The skin settings group ID.
*
* @return
* A fully-populated skin settings group object.
*/
function skinr_context_group_load_unchanged($gid) {
// Load an uncached version of the skin settings object. Specify order to
// ensure consistent import/export.
$group = db_query("SELECT gid, module, element, title, description, conditions, condition_mode, weight, status FROM {skinr_groups} WHERE gid = :gid", array(
':gid' => $gid,
))
->fetchObject();
// Unserialize options array.
if ($group) {
$group->conditions = unserialize($group->conditions);
// Let modules modify the skin settings group.
module_invoke_all('skinr_context_group_load', $group);
}
return $group;
}
/**
* Returns all default skin settings group objects.
*/
function _skinr_context_group_get_defaults() {
$default_groups =& drupal_static(__FUNCTION__);
if (!isset($default_groups)) {
if ($cached = cache_get('skinr_context_group_defaults')) {
$default_skins = $cached->data;
return $default_skins;
}
// Don't use module_invoke_all() to prevent oddly merged defaults.
$default_groups = array();
foreach (module_implements('skinr_context_group_defaults') as $module) {
$function = $module . '_skinr_context_group_defaults';
if (function_exists($function)) {
$result = call_user_func_array($function, array());
if (isset($result) && is_array($result)) {
$default_groups = array_merge($default_groups, $result);
}
elseif (isset($result)) {
$default_groups[] = $result;
}
}
}
// Let modules modify the skin settings group.
drupal_alter('skinr_context_group_defaults', $default_groups);
cache_set('skinr_context_group_defaults', $default_groups);
}
return $default_groups;
}
/**
* Imports default skin settings group objects from code into database.
*
* @param $module_name
* Limit importing of defaults to a single module.
* @param $force
* If FALSE (default) the default skin settings group will only be imported if
* it doesn't exist, or if storage is default in code. If TRUE, the skin
* settings group in code will always be overwritten.
*
* @return
* If an import failed, returns FALSE. If all imports succeeded, returns TRUE.
*/
function skinr_context_group_defaults_import($module_name = NULL, $force = FALSE) {
if (isset($module_name)) {
if (!($default_groups = module_invoke($module_name, 'skinr_context_group_defaults'))) {
$default_groups = array();
}
drupal_alter('skinr_context_group_defaults', $default_groups);
}
else {
$default_groups = _skinr_context_group_get_defaults();
}
$status = TRUE;
foreach ($default_groups as $group) {
$status = skinr_context_group_import($group, $force) && $status;
}
return $status;
}
/**
* Revert a skin settings group object that's stored in code to its default state.
*
* @param $gid
* The skin settings group ID.
*/
function skinr_context_group_revert($gid) {
$default_groups = _skinr_context_group_get_defaults();
if (!isset($default_groups[$gid])) {
return FALSE;
}
return skinr_context_group_import($default_groups[$gid], TRUE);
}
/**
* Import a skin settigns group object as defined in skinr_context_group_defaults().
*
* @param $default_group
* A skin settings group object.
* @param $force
* If FALSE (default) the default skin settings group will only be imported if
* it doesn't exist, or if storage is default in code. If TRUE, the skin
* settings group in code will always be overwritten.
*
* @return
* If import failed, returns FALSE. If it succeeded, returns TRUE.
*/
function skinr_context_group_import($default_group, $force = FALSE) {
// Make sure we don't modify the cached default group array.
$group = clone $default_group;
// Functionality is abstracted for use in skinr_context_group_storage().
_skinr_context_group_import($group);
if (!$force) {
// Load existing skin configuration from DB.
if ($db_group = skinr_context_group_load_unchanged($group->gid)) {
// Sync status.
$group->status = $db_group->status;
if ($group != $db_group) {
// Group exists and is overridden, so cancel import.
watchdog('skinr', 'Canceled import of group with ID %gid. It is overridden.', array(
'%gid' => $group->gid,
), WATCHDOG_WARNING);
return FALSE;
}
}
}
if ($status = skinr_context_group_save($group)) {
watchdog('skinr', 'Imported group with ID %gid.', array(
'%gid' => $group->gid,
), WATCHDOG_NOTICE);
}
else {
watchdog('skinr', 'Failed to import group with ID %gid.', array(
'%gid' => $group->gid,
), WATCHDOG_WARNING);
}
return $status;
}
function _skinr_context_group_import(&$group) {
// Let modules modify the skin settings group.
drupal_alter('skinr_context_group_import', $group);
}
/**
* Output a settings group object as code suitable for skinr_context_group_defaults().
*
* @param $group
* A skin settings group object.
* @param $prefix
* A string to prefix the code with, used to indent the resulting code.
*
* @return
* A string.
*/
function skinr_context_group_export($group, $prefix = '') {
// Make sure we don't modify the cached group object.
$group = clone $group;
// Let modules modify the skin settings group.
drupal_alter('skinr_context_group_export', $group, $prefix);
$output = skinr_object_export($group, 'group', $prefix);
$output .= $prefix . "\$groups['{$group->gid}'] = \$group;\n";
return $output;
}
/**
* Returns a skin settings group's storage method.
*
* @param $skin
* A skin settings group.
*
* @return
* SKINR_STORAGE_IN_DATABASE if stored in the database,
* SKINR_STORAGE_IN_CODE if stored in code,
* SKINR_STORAGE_IN_CODE_OVERRIDDEN if stored in code and overridden in db.
*/
function skinr_context_group_storage($group) {
$default_groups = _skinr_context_group_get_defaults();
$storage = SKINR_STORAGE_IN_DATABASE;
if (isset($default_groups[$group->gid])) {
$default_group = clone $default_groups[$group->gid];
// Make sure group has same processing as import.
_skinr_context_group_import($default_group);
// API version is only used for export.
unset($default_group->api_version);
// Status shouldn't influence overridden.
$default_group->status = $group->status;
$storage = SKINR_STORAGE_IN_CODE;
if ($default_group != $group) {
// Default was overridden.
$storage = SKINR_STORAGE_IN_CODE_OVERRIDDEN;
}
}
return $storage;
}
/**
* Get skin settings group IDs.
*
* @param $filter_by
* An associative array whose keys are:
* - module: (optional) The module.
* - element: (optional) The element ID.
*
* @return
* An array of skin settings group IDs.
*/
function skinr_context_group_get_gids($filter_by = array()) {
$query = db_select('skinr_groups', 'g')
->fields('g', array(
'gid',
));
if (isset($filter_by['module'])) {
$query
->condition('module', $filter_by['module']);
}
if (isset($filter_by['element'])) {
$query
->condition('element', $filter_by['element']);
}
// Take weight into account.
$query
->orderBy('weight');
$query
->orderBy('gid');
return $query
->execute()
->fetchCol();
}
/**
* Get skin settings IDs for grouped skin settings.
*
* @param $filter_by
* An associative array whose keys are:
* - theme: (optional) The theme.
* - module: (optional) The module.
* - element: (optional) The element ID.
* - gid: (optional) The group ID.
* - skin: (optional) The skin name.
* - status: (optional) Boolean indicating whether or not this skin
* configuration is enabled.
*
* @return
* An array of skin settings IDs.
*/
function skinr_context_group_get_sids($filter_by = array()) {
$query = db_select('skinr_skins', 's');
$query
->join('skinr_group_skins', 'gs', 's.sid = gs.sid');
$query
->fields('s', array(
'sid',
));
if (isset($filter_by['theme'])) {
$query
->condition('s.theme', $filter_by['theme']);
}
if (isset($filter_by['module'])) {
$query
->condition('s.module', $filter_by['module']);
}
if (isset($filter_by['element'])) {
$query
->condition('s.element', $filter_by['element']);
}
if (isset($filter_by['gid'])) {
$query
->condition('gs.gid', $filter_by['gid']);
}
if (isset($filter_by['skin'])) {
$query
->condition('s.skin', $filter_by['skin']);
}
if (isset($filter_by['status'])) {
$query
->condition('s.status', $filter_by['status']);
}
return $query
->execute()
->fetchCol();
}
/**
* Helper function to create a context object from a skin settings group.
*
* @param $group
* Skinr settings group object.
*
* @return
* A context object.
*/
function skinr_context_group_to_context($group) {
$context = (object) array(
'name' => 'skinr_group__' . $group->gid,
'description' => !empty($group->description) ? t('@title: @description', array(
'@title' => $group->title,
'@description' => $group->description,
)) : check_plain($group->title),
'tag' => 'Skinr',
'conditions' => $group->conditions,
'reactions' => array(),
'condition_mode' => $group->condition_mode,
);
return $context;
}
/**
* Implements hook_ctools_plugin_api().
*/
function skinr_context_ctools_plugin_api($module, $api) {
if ($module == "context" && $api == "context") {
return array(
"version" => 3,
);
}
}
/**
* Implements hook_context_default_contexts().
*/
function skinr_context_context_default_contexts() {
$contexts = array();
foreach (skinr_context_group_load_multiple(FALSE) as $group) {
$context = skinr_context_group_to_context($group);
$context->disabled = FALSE;
$context->api_version = 3;
$contexts[$context->name] = $context;
}
return $contexts;
}
/**
* Implements hook_skinr_skin_presave().
*/
function skinr_context_skinr_skin_presave($skin) {
if (!empty($skin->gid)) {
// Load group object.
if ($group = skinr_context_group_load($skin->gid)) {
if (!$group->status) {
// Disable skin status if group is disabled.
$skin->status = 0;
}
}
}
}
/**
* Implements hook_skinr_skin_insert().
*/
function skinr_context_skinr_skin_insert($skin) {
if (!empty($skin->gid)) {
$gs = (object) array(
'gid' => $skin->gid,
'sid' => $skin->sid,
);
drupal_write_record('skinr_group_skins', $gs);
}
}
/**
* Implements hook_skinr_skin_delete().
*/
function skinr_context_skinr_skin_delete($skin) {
if (!empty($skin->gid)) {
db_delete('skinr_group_skins')
->condition('sid', $skin->sid)
->execute();
}
}
/**
* Implements hook_skinr_skin_load().
*/
function skinr_context_skinr_skin_load($skin) {
$query = db_select('skinr_group_skins', 'gs');
$query
->fields('gs', array(
'gid',
));
$query
->condition('sid', $skin->sid);
$skin->gid = $query
->execute()
->fetchField();
}
/**
* Implements hook_skinr_skin_defaults_alter().
*/
function skinr_context_skinr_skin_defaults_alter(&$default_skins) {
foreach ($default_skins as &$skin) {
if (!isset($skin->gid)) {
_skinr_context_add_default_group($skin);
}
}
}
/**
* Helper function to add a new default group to a skin configuration.
*/
function _skinr_context_add_default_group(&$skin) {
// Lookup existing group. Grab the one with the lowest weight for this set.
$params = array(
'module' => $skin->module,
'element' => $skin->element,
);
$gids = skinr_context_group_get_gids($params);
$gid = reset($gids);
if (!$gid) {
// Create a group.
$title = t('Default');
$group = (object) array(
'gid' => $skin->module . ':' . $skin->element . ':' . strtolower($title),
'module' => $skin->module,
'element' => $skin->element,
'title' => $title,
'description' => '',
'conditions' => array(
'sitewide' => array(
'values' => array(
1 => 1,
),
),
),
'condition_mode' => CONTEXT_CONDITION_MODE_OR,
'weight' => 0,
'status' => 1,
);
skinr_context_group_save($group);
$gid = $group->gid;
}
$skin->gid = $gid;
// Simulate insert to ensure group is linked.
//skinr_context_skinr_skin_insert($skin);
}
/**
* Function used by uasort to sort classes by weight.
*
* @see skinr_context_skinr_preprocess_alter()
*/
function skinr_context_sort_weight($a, $b) {
$a_weight = is_object($a) && isset($a->weight) ? $a->weight : 0;
$b_weight = is_object($b) && isset($b->weight) ? $b->weight : 0;
if ($a_weight == $b_weight) {
return 0;
}
return $a_weight < $b_weight ? -1 : 1;
}
/**
* Implements hook_skinr_preprocess_alter().
*/
function skinr_context_skinr_preprocess_alter(&$skins, $context) {
$contexts = context_active_contexts();
foreach ($skins as $key => $skin) {
if (!empty($skin->gid) && ($group = skinr_context_group_load($skin->gid))) {
// Remove skins for groups that arent in the right context.
if (!isset($contexts['skinr_group__' . $skin->gid])) {
unset($skins[$key]);
}
// Set group based weight on skins.
$skin->weight = $group->weight;
}
}
// Reorder by weight.
uasort($skins, 'skinr_context_sort_weight');
}
/**
* Implements hook_modules_enabled().
*/
function skinr_context_modules_enabled($modules) {
foreach ($modules as $module) {
skinr_context_group_defaults_import($module);
}
}
Functions
Name | Description |
---|---|
skinr_context_context_default_contexts | Implements hook_context_default_contexts(). |
skinr_context_ctools_plugin_api | Implements hook_ctools_plugin_api(). |
skinr_context_group_defaults_import | Imports default skin settings group objects from code into database. |
skinr_context_group_delete | Delete a skin group object. |
skinr_context_group_delete_multiple | Delete multiple skin settings group objects. |
skinr_context_group_export | Output a settings group object as code suitable for skinr_context_group_defaults(). |
skinr_context_group_get_gids | Get skin settings group IDs. |
skinr_context_group_get_sids | Get skin settings IDs for grouped skin settings. |
skinr_context_group_import | Import a skin settigns group object as defined in skinr_context_group_defaults(). |
skinr_context_group_load | Load a skin settings group object from the database. |
skinr_context_group_load_multiple | Load skin settings group objects from the database. |
skinr_context_group_load_unchanged | Load an uncached version of a skin settings group object. |
skinr_context_group_revert | Revert a skin settings group object that's stored in code to its default state. |
skinr_context_group_save | Save a skin group object. |
skinr_context_group_storage | Returns a skin settings group's storage method. |
skinr_context_group_to_context | Helper function to create a context object from a skin settings group. |
skinr_context_group_validate | Validate a skin group object. |
skinr_context_hook_info | Implements hook_hook_info(). |
skinr_context_modules_enabled | Implements hook_modules_enabled(). |
skinr_context_module_implements_alter | Implements hook_module_implements_alter(). |
skinr_context_skinr_preprocess_alter | Implements hook_skinr_preprocess_alter(). |
skinr_context_skinr_skin_defaults_alter | Implements hook_skinr_skin_defaults_alter(). |
skinr_context_skinr_skin_delete | Implements hook_skinr_skin_delete(). |
skinr_context_skinr_skin_insert | Implements hook_skinr_skin_insert(). |
skinr_context_skinr_skin_load | Implements hook_skinr_skin_load(). |
skinr_context_skinr_skin_presave | Implements hook_skinr_skin_presave(). |
skinr_context_sort_weight | Function used by uasort to sort classes by weight. |
_skinr_context_add_default_group | Helper function to add a new default group to a skin configuration. |
_skinr_context_group_get_defaults | Returns all default skin settings group objects. |
_skinr_context_group_import |