help page for full documentation.', array('@skinr-help' => url('admin/advanced_help/skinr'))); } else { return t('Please download and enable the Advanced Help module for full Skinr documentation.'); } break; } } /** * Implementation of hook_init(). */ function skinr_init() { static $run = FALSE; if (!$run) { module_load_include('inc', 'skinr', 'skinr.handlers'); skinr_module_include('skinr.inc'); $run = TRUE; } } /** * Implementation of hook_preprocess(). */ function skinr_preprocess(&$vars, $hook) { // Let's make sure this has been run. There have been problems where other // modules implement a theme function in their hook_init(), so we make doubly // sure that the includes are included. skinr_init(); $skinr_config = skinr_fetch_config(); $current_theme = skinr_current_theme(); $theme_registry = theme_get_registry(); $original_hook = $hook; if (isset($theme_registry[$hook]['original hook'])) { $original_hook = $theme_registry[$hook]['original hook']; } foreach ($skinr_config as $module => $settings) { if (!empty($settings['preprocess'][$original_hook])) { $preprocess_settings = $settings['preprocess'][$original_hook]; $sids = skinr_handler('preprocess_index_handler', 'preprocess', $preprocess_settings['index_handler'], $vars); if ($extracted = skinr_skin_extract($module, $sids, $settings, $current_theme)) { foreach ($extracted['css'] as $file) { if ($file['enabled']) { _skinr_add_file($file['path'], 'css', $file['media']); } } foreach ($extracted['js'] as $file) { if ($file['enabled']) { _skinr_add_file($file['path'], 'js'); } } if (!empty($extracted['template'])) { $vars['template_files'][] = $extracted['template']; } $vars['skinr'] = implode(' ', $extracted['classes']); $vars['skinr_array'] = $extracted['classes']; // Need to add a hook for skinr_ui to plug into. $data = array( 'hook' => $hook, 'vars' => &$vars, 'skin' => &$extracted, ); drupal_alter('skinr_preprocess', $data); // Reset styles to make sure all are included. $vars['styles'] = drupal_get_css(); $vars['scripts'] = drupal_get_js(); } } } } function skinr_skin_extract($module, $sids, $settings, $theme = NULL, $reset = FALSE) { if (empty($sids)) { return FALSE; } if (!is_array($sids)) { $sids = array($sids); } if (is_null($theme)) { $theme = skinr_current_theme(); } $info = skinr_skin_data(); $extracted = array( 'module' => $module, 'sids' => $sids, 'classes' => array(), 'css' => array(), 'js' => array(), 'template' => array(), ); $skins = array(); foreach ($sids as $sid) { if ($skinr = skinr_get($theme, $module, $sid, $reset)) { $skins = $skinr->skins + $skins; } // Only need to reset the first time. $reset = FALSE; } // Allow other modules to alter the skinr skins array. // @todo Fix this to work with skinr ui. drupal_alter('skinr_skins', $skins, $module, $sids, $settings); $extracted['css'] = skinr_skin_get_files($skins, 'css', $theme); $extracted['js'] = skinr_skin_get_files($skins, 'js', $theme); // Add template files. if (!empty($skins['_template'])) { $extracted['template'] = $skins['_template']; unset($skins['_template']); } $extracted['classes'] = skinr_flatten_skins_array($skins); return $extracted; } /** * Helper function to fetch all css or js files from an array of skins. * * @param $skins * A an array of available skins. * @param $type * Either 'css' or 'js', depending on which files you wish to retrieve from * these skins. * @param $theme * The theme from which to grab these files. Defaults to the current theme. * * @return * An array of file data. */ function skinr_skin_get_files($skins, $type, $theme = NULL) { if (empty($theme)) { $theme = skinr_current_theme(); } $info = skinr_skin_data(); $files = array(); if ($type == 'css') { foreach ($skins as $skin => $classes) { // Add custom CSS files. if (isset($info[$theme]->skins[$skin])) { if (!empty($info[$theme]->skins[$skin]['stylesheets'])) { foreach ($info[$theme]->skins[$skin]['stylesheets'] as $media => $stylesheets) { foreach ($stylesheets as $file => $path) { $files[] = array( 'file' => $file, 'path' => $path, 'media' => $media, 'enabled' => TRUE, 'skin' => $skin, 'options' => 0, ); } } } foreach ($info[$theme]->skins[$skin]['options'] as $option_id => $option) { if (!empty($option['stylesheets'])) { foreach ($option['stylesheets'] as $media => $stylesheets) { foreach ($stylesheets as $file => $path) { $enabled = FALSE; if (is_array($classes)) { if (in_array($option['class'], $classes)) { $enabled = TRUE; } } else { if ($option['class'] == $classes) { $enabled = TRUE; } } $files[] = array( 'file' => $file, 'path' => $path, 'media' => $media, 'enabled' => $enabled, 'skin' => $skin, 'options' => $option_id, ); } } } } } } } elseif ($type == 'js') { foreach ($skins as $skin => $classes) { // Add custom JS files. if (isset($info[$theme]->skins[$skin])) { if (isset($info[$theme]->skins[$skin]['scripts'])) { foreach ($info[$theme]->skins[$skin]['scripts'] as $file => $path) { $files[] = array( 'file' => $file, 'path' => $path, 'enabled' => TRUE, 'skin' => $skin, 'options' => 0, ); } } foreach ($info[$theme]->skins[$skin]['options'] as $option_id => $option) { if (isset($option['scripts'])) { foreach ($option['scripts'] as $file => $path) { $enabled = FALSE; if (is_array($classes)) { if (in_array($option['class'], $classes)) { $enabled = TRUE; } } else { if ($option['class'] == $classes) { $enabled = TRUE; } } $files[] = array( 'file' => $file, 'path' => $path, 'enabled' => $enabled, 'skin' => $skin, 'options' => $option_id, ); } } } } } } return $files; } /** * Helper fuction to add CSS and JS files. * * The function checks an array of paths for the existence of the file to account for base themes. */ function _skinr_add_file($filename, $type, $media = NULL) { if (file_exists($filename)) { if ($type == 'css') { drupal_add_css($filename, 'theme', $media); } else { drupal_add_js($filename, 'theme'); } } } /** * Helper function to flatten an array of classes settings. */ function skinr_flatten_skins_array($skins) { $return = array(); foreach ($skins as $entry) { if (is_array($entry)) { foreach ($entry as $subentry) { if (!empty($subentry)) { $return[] = check_plain($subentry); } } } elseif (!empty($entry)) { $return[] = check_plain($entry); } } return $return; } // ------------------------------------------------------------------ // Page rule functions. /** * Save a skinr page rule object. */ function skinr_rule_save($rule) { drupal_write_record('skinr_rules', $rule, !empty($rule->rid) ? array('rid') : array()); } /** * Load a skinr page rule object. */ function skinr_rule_load($rid = NULL) { if (is_null($rid)) { $rules = array(); $result = db_query("SELECT * FROM {skinr_rules}"); while ($rule = db_fetch_object($result)) { $rule->roles = unserialize($rule->roles); $rules[] = $rule; } return $rules; } else { $result = db_query("SELECT * FROM {skinr_rules} WHERE rid = %d", $rid); if ($rule = db_fetch_object($result)) { $rule->roles = unserialize($rule->roles); return $rule; } return FALSE; } } /** * Delete a skinr page rule object. */ function skinr_rule_delete($rid) { if ($rule = skinr_rule_load($rid)) { db_query("DELETE FROM {skinr_rules} WHERE rid = %d", $rule->rid); db_query("DELETE FROM {skinr} WHERE module = '%s' AND sid = '%s'", 'page', $rule->rid); } } function skinr_rule_visible($rid) { global $user; if ($rule = skinr_rule_load($rid)) { $page_match = TRUE; if (!empty($record['roles']) && ($user->uid != 1) && !count(array_intersect(array_keys($user->roles), $rule->roles))) { return FALSE; } // Match path if necessary if ($rule->pages) { if ($rule->visibility < 2) { $path = drupal_get_path_alias($_GET['q']); // Compare with the internal and path alias (if any). $page_match = drupal_match_path($path, $rule->pages); if ($path != $_GET['q']) { $page_match = $page_match || drupal_match_path($_GET['q'], $rule->pages); } // When $rule->visibility has a value of 0, the item is displayed on // all pages except those listed in $rule->pages. When set to 1, it // is displayed only on those pages listed in $rule->pages. $page_match = !($rule->visibility xor $page_match); } else { // PHP. $page_match = drupal_eval($rule->pages); } } return $page_match; } return FALSE; } // ------------------------------------------------------------------ // Include file helpers. /** * Load skinr files on behalf of modules. */ function skinr_module_include($file) { foreach (skinr_get_module_apis() as $module => $info) { if (file_exists("./$info[path]/$module.$file")) { require_once "./$info[path]/$module.$file"; } } } /** * Get a list of modules that support skinr. */ function skinr_get_module_apis() { static $cache = NULL; if (is_null($cache)) { $cache = array(); foreach (module_implements('skinr_api') as $module) { $function = $module .'_skinr_api'; $info = $function(); if (isset($info['api']) && $info['api'] == 1.000) { if (!isset($info['path'])) { $info['path'] = drupal_get_path('module', $module); } $cache[$module] = $info; } } } return $cache; } // ----------------------------------------------------------------------- // Skinr data handling functions. /** * Validate a skinr object. * * @param $skinr * A skinr object. * * @return * TRUE on success, FALSE on failure. */ function skinr_validate(&$skinr) { if (!isset($skinr->theme) || !isset($skinr->module) || !isset($skinr->sid) || !isset($skinr->skins)) { return FALSE; } if (!isset($skinr->settings)) { $skinr->settings = array(); } if (!is_array($skinr->skins) || !is_array($skinr->settings)) { return FALSE; } // Strip empty skins. $skinr->skins = _skinr_array_strip_empty($skinr->skins); return TRUE; } /** * Save a skinr object. * * @param $skinr * A skinr object. * * @return * TRUE on success, FALSE on failure. */ function skinr_set($skinr) { // Make sure we're getting valid data. if (!skinr_validate($skinr)) { return FALSE; } if (empty($skinr->skins) && empty($skinr->settings)) { // Delete the db entry if it exists. db_query("DELETE FROM {skinr} WHERE theme = '%s' AND module = '%s' AND sid = '%s'", $skinr->theme, $skinr->module, $skinr->sid); } else { // Let's save the data. if (skinr_get($skinr->theme, $skinr->module, $skinr->sid) !== FALSE) { // Record exists, so let's update. drupal_write_record('skinr', $skinr, array('theme', 'module', 'sid')); } else { // Insert a new record. drupal_write_record('skinr', $skinr); } } return TRUE; } /** * Retrieves the desired skinr object. * * @return * A skinr object if both $module and $sid are specified. An array of skinr * objects if only $module is specified. An array of all skinr objects for a * theme if neither $module nor $sid is specified. FALSE on failure. */ function skinr_get($theme = NULL, $module = NULL, $sid = NULL, $reset = FALSE) { static $cache = array(); if (is_null($theme)) { $theme = skinr_current_theme(); } if ($reset) { $cache = array(); } if (!isset($cache[$theme][$module][$sid])) { if (!isset($cache[$theme])) { $cache[$theme] = array(); } if (!is_null($module) && !isset($cache[$theme][$module])) { $cache[$theme][$module] = array(); } if (!is_null($module) && !is_null($sid)) { // Fetch just this sid. $result = db_query("SELECT theme, module, sid, settings, skins FROM {skinr} WHERE theme = '%s' AND module = '%s' AND sid = '%s'", $theme, $module, $sid); } elseif (!is_null($module)) { // Fetch all settings for this theme and module. $result = db_query("SELECT theme, module, sid, settings, skins FROM {skinr} WHERE theme = '%s' AND module = '%s'", $theme, $module); } else { // Fetch all settings for this theme. $result = db_query("SELECT theme, module, sid, settings, skins FROM {skinr} WHERE theme = '%s'", $theme); } while ($skinr = db_fetch_object($result)) { $skinr->settings = unserialize($skinr->settings); $skinr->skins = unserialize($skinr->skins); $cache[$skinr->theme][$skinr->module][$skinr->sid] = $skinr; } } if (is_null($sid) && is_null($module)) { // Return all the skinrs for the theme. if (isset($cache[$theme])) { return $cache[$theme]; } } elseif(is_null($sid)) { // Return all the skinrs for the module. if (isset($cache[$theme][$module])) { return $cache[$theme][$module]; } } elseif (isset($cache[$theme][$module][$sid])) { return $cache[$theme][$module][$sid]; } return FALSE; } /** * Helper function to remove empty skins from an array. */ function _skinr_array_strip_empty($array) { $new_array = array(); foreach ($array as $key => $value) { if (is_array($value)) { $value = _skinr_array_strip_empty($value); } if (!empty($value)) { $new_array[$key] = $value; } } return $new_array; } /** * Helper function to retrieve the current theme. * The global variable $theme_key doesn't work for our purposes when an admin * theme is enabled. * * @param $exculde_admin_theme * Optional. Set to TRUE to exclude the admin theme from posible themes to * return. */ function skinr_current_theme($exclude_admin_theme = FALSE) { global $user, $custom_theme; if (!empty($user->theme)) { $current_theme = $user->theme; } elseif (!empty($custom_theme) && !($exclude_admin_theme && $custom_theme == variable_get('admin_theme', '0'))) { // Don't return the admin theme if we're editing skinr settings. $current_theme = $custom_theme; } else { $current_theme = variable_get('theme_default', 'garland'); } return $current_theme; } /** * Prepare defaults for skins. * * @return * An array of default skinset settings. */ function skinr_skins_default() { return array( 'description' => '', 'screenshot' => 'screenshot.png', 'php' => DRUPAL_MINIMUM_PHP, 'skinr' => array(), ); } /** * Prepare defaults for skinr options. * * @return * An array of default skinset options settings. */ function skinr_group_default() { return array( 'title' => '', 'description' => '', 'collapsible' => TRUE, 'collapsed' => FALSE, 'weight' => NULL, ); } /** * Prepare defaults for skins. * * @return * An array of default skins settings. */ function skinr_skin_default() { return array( 'title' => '', 'type' => 'checkboxes', 'description' => '', 'features' => array('*'), 'templates' => array(), 'group' => '', 'options' => array(), 'stylesheets' => array(), 'scripts' => array(), 'weight' => NULL, ); } /** * Retrieves all the Skinr skins from theme parents. Theme skins * will override any skins of the same name from its parents. */ function skinr_inherited_skins($theme) { $themes = _system_theme_data(); $all_skins = $skins = array(); $base_theme = (!empty($themes[$theme]->info['base theme'])) ? $themes[$theme]->info['base theme'] : ''; while ($base_theme) { // Add in path info here. $base_skins = (!empty($themes[$base_theme]->info['skinr'])) ? (array)$themes[$base_theme]->info['skinr'] : array(); $base_path = $path_root = dirname($themes[$base_theme]->filename); _skinr_add_paths_to_files($base_skins, $base_path); $all_skins[] = $base_skins; $base_theme = (!empty($themes[$base_theme]->info['base theme'])) ? $themes[$base_theme]->info['base theme'] : ''; } array_reverse($all_skins); foreach ($all_skins as $new_skin) { $skins = array_merge($skins, $new_skin); } return $skins; } /** * Helper function to scan and collect skin .info data. * * @return * An associative array of skins information. */ function _skinr_skins_data() { static $skins_info = array(); if (empty($skins_info)) { // Find skins. $mask = '\.info$'; $directory = 'skins'; $skinsets = drupal_system_listing($mask, $directory); // Find skins in theme folders. $themes = _system_theme_data(); foreach ($themes as $theme) { $dir = dirname($theme->filename) .'/'. $directory; $skinsets = array_merge($skinsets, file_scan_directory($dir, $mask, array('.', '..', 'CVS'), 0, TRUE, 'name', 1)); } // Find skins in module folders. foreach (skinr_get_module_apis() as $module => $info) { if (isset($info['skins']) && $info['skins'] == TRUE) { $dir = dirname($info['path'] .'/'. $directory); $skinsets = array_merge($skinsets, file_scan_directory($dir, $mask, array('.', '..', 'CVS'), 0, TRUE, 'name', 1)); } } $defaults = skinr_skins_default(); foreach ($skinsets as $key => $skinset) { $skinsets[$key]->info = drupal_parse_info_file($skinset->filename) + $defaults; // Give the screenshot proper path information. if (!empty($skinsets[$key]->info['screenshot'])) { $skinsets[$key]->info['screenshot'] = dirname($skinsets[$key]->filename) .'/'. $skinsets[$key]->info['screenshot']; } // Invoke hook_skinr_info_alter() to give installed modules a chance to // modify the data in the .info files if necessary. drupal_alter('skinr_info', $skinsets[$key]->info, $skinsets[$key]); } $skins_info = $skinsets; } return $skins_info; } /** * Helper function to process a skin or theme .info file. * * @return * A skinset. */ function _skinr_skinset($info) { $skinset = array( 'options' => array('groups' => array()), 'skins' => array(), ); if (!empty($info->info['skinr'])) { $path_root = dirname($info->filename); $skinr_info = (array)$info->info['skinr']; // Store skinr options. if (!empty($skinr_info['options'])) { $skinset['options'] = $skinr_info['options']; unset($skinr_info['options']); if (!isset($skinset['options']['groups'])) { $skinset['options']['groups'] = array(); } $defaults = skinr_group_default(); foreach ($skinset['options']['groups'] as $id => $group) { $skinset['options']['groups'][$id] = array_merge($defaults, $skinset['options']['groups'][$id]); $skinset['options']['groups'][$id]['collapsible'] = (bool)$skinset['options']['groups'][$id]['collapsible']; $skinset['options']['groups'][$id]['collapsed'] = (bool)$skinset['options']['groups'][$id]['collapsed']; $skinset['options']['groups'][$id]['weight'] = $skinset['options']['groups'][$id]['weight']; } } // Add paths to $skinr_info. _skinr_add_paths_to_files($skinr_info, $path_root); // Inherit skins from parent theme, if inherit_skins is set to true. if (!empty($skinset['options']['inherit_skins'])) { // Paths get automatically added to base theme info. $base_info = skinr_inherited_skins($info->name); // Merge base theme and current. $skinr_info = array_merge($base_info, $skinr_info); } $defaults = skinr_skin_default(); foreach ($skinr_info as $id => $skin) { if (!is_array($skin)) { continue; } $skinset['skins'][$id] = array( 'title' => isset($skin['title']) ? $skin['title'] : $defaults['title'], 'type' => isset($skin['type']) ? $skin['type'] : $defaults['type'], 'description' => isset($skin['description']) ? $skin['description'] : $defaults['description'], 'features' => isset($skin['features']) ? $skin['features'] : $defaults['features'], 'templates' => isset($skin['templates']) ? $skin['templates'] : $defaults['templates'], 'group' => !empty($skin['group']) && !empty($skinset['options']['groups'][$skin['group']]) ? $skin['group'] : $defaults['group'], 'options' => isset($skin['options']) ? $skin['options'] : $defaults['options'], 'stylesheets' => isset($skin['stylesheets']) ? $skin['stylesheets'] : $defaults['stylesheets'], 'scripts' => isset($skin['scripts']) ? $skin['scripts'] : $defaults['scripts'], 'weight' => isset($skin['weight']) ? $skin['weight'] : $defaults['weight'], ); } } return $skinset; } function _skinr_add_paths_to_files(&$skinr_info, $path_root) { foreach ($skinr_info as $id => $skin) { if (!is_array($skin)) { continue; } // Give the stylesheets proper path information. if (!empty($skin['stylesheets'])) { $skinr_info[$id]['stylesheets'] = _skinr_add_path_to_files($skin['stylesheets'], $path_root, 'css'); } // Give the scripts proper path information. if (!empty($skin['scripts'])) { $skinr_info[$id]['scripts'] = _skinr_add_path_to_files($skin['scripts'], $path_root, 'js'); } if (!empty($skin['options'])) { foreach ($skin['options'] as $oid => $option) { if (!empty($option['stylesheets'])) { $skinr_info[$id]['options'][$oid]['stylesheets'] = _skinr_add_path_to_files($option['stylesheets'], $path_root, 'css'); } if (isset($option['scripts'])) { $skinr_info[$id]['options'][$oid]['scripts'] = _skinr_add_path_to_files($option['scripts'], $path_root, 'js'); } } } } } /** * Helper function to prepend a path to an array of stylesheets or scripts in a .info file. * * @param $files * A an array of filenames that need the path prepended. * @param $path * The path to prepend. * @param $type * Either 'css' or 'js', depending on which files you wish to retrieve from * these skins. * * @return * An array of files with the root path added. */ function _skinr_add_path_to_files($files, $path, $type) { if ($type == 'css') { $pathed_stylesheets = array(); foreach ($files as $media => $stylesheets) { foreach ($stylesheets as $stylesheet) { $pathed_stylesheets[$media][$stylesheet] = $path .'/'. $stylesheet; } } return $pathed_stylesheets; } elseif ($type == 'js') { $pathed_scripts = array(); foreach ($files as $script) { $pathed_scripts[$script] = $path .'/'. $script; } return $pathed_scripts; } return FALSE; } /** * Helper function to process an array of skins or themes .info files. * * @param $type * Either 'theme' or 'skinset'. * @param $refresh * Whether to reload the list of skinsets from the database or not. * * @return * An array of skinsets. */ function skinr_skinsets($type, $refresh = FALSE) { static $skinsets = array('theme' => array(), 'skinset' => array()); if ($refresh) { $skinsets[$type] = array(); } if (empty($skinsets[$type])) { $themes = _system_theme_data(); if ($type == 'theme') { foreach ($themes as $theme) { $skinset = new StdClass(); $skinset->filename = $theme->filename; $skinset->name = $theme->name; $skinset->status = isset($theme->status) ? 1 : 0; $skinset->info = $theme->info; $skinsets[$type][$skinset->name] = $skinset; } } elseif ($type == 'skinset') { $result = db_query("SELECT * FROM {skinr_skinsets}"); while ($skinset = db_fetch_object($result)) { if (file_exists($skinset->filename)) { $skinset->info = unserialize($skinset->info); $skinsets[$type][$skinset->name] = $skinset; } } } $default_status = array(); foreach ($themes as $theme) { $default_status[$theme->name] = $theme->name; } foreach ($skinsets[$type] as $key => $skinset) { $skinset->type = $type; $additional = _skinr_skinset($skinset); $skinset->options = $additional['options']; $skinset->skins = $additional['skins']; $statuses = skinr_skinset_statuses($skinset->name); foreach ($skinset->skins as $skin_name => $skin) { $skinset->skins[$skin_name]['status'] = !empty($statuses[$skin_name]) ? $statuses[$skin_name] : $default_status; } } } return $skinsets[$type]; } /** * Return an array of statuses of each skin in a skinset for each theme. * * @param $skinset_name * The name of the skinset of which to load the statuses. * @param $refresh * Whether to reload the list of statuses for a skin from the database or not. * * @return * Array of statuses for individual skins in a skinset. */ function skinr_skinset_statuses($skinset_name, $refresh = FALSE) { static $statuses = array(); if (isset($refresh)) { $statuses[$skinset_name] = array(); } if (empty($statuses[$skinset_name])) { $result = db_query("SELECT * FROM {skinr_skins} WHERE name = '%s'", $skinset_name); while ($skinr_skin = db_fetch_object($result)) { $statuses[$skinset_name][$skinr_skin->skin] = unserialize($skinr_skin->status); } } return $statuses[$skinset_name]; } /** * Rebuild, save, and return data about all currently available skinsets. * * @return * Array of all available skinsets and their data. */ function skinr_rebuild_skinset_data() { $skinsets = _skinr_skins_data(); skinr_get_files_database($skinsets); db_query("DELETE FROM {skinr_skinsets}"); foreach ($skinsets as $skinset) { db_query("INSERT INTO {skinr_skinsets} (filename, name, status, info) VALUES ('%s', '%s', '%s', '%s')", $skinset->filename, $skinset->name, isset($skinset->status) ? $skinset->status : 0, serialize($skinset->info)); } return $skinsets; } /** * Implementation of hook_flush_caches(). */ function skinr_flush_caches() { skinr_rebuild_skinset_data(); return array(); } /** * Retrieves the current status of an array of files in the skinr_skinsets table. * * @param $files * An array of files to check. */ function skinr_get_files_database(&$files) { // Extract current files from database. $result = db_query("SELECT filename, name, status FROM {skinr_skinsets}"); while ($file = db_fetch_object($result)) { if (isset($files[$file->name]) && is_object($files[$file->name])) { $file->uri = $file->filename; foreach ($file as $key => $value) { if (!isset($files[$file->name]) || !isset($files[$file->name]->$key)) { $files[$file->name]->$key = $value; } } } } } /** * Themes are allowed to set Skinr skins in their .info files. * * @return * An array of skinsets keyed by themename. * * @todo Use DB caching. No need to keep processing things every page load. */ function skinr_skin_data() { static $cache = NULL; if (is_null($cache)) { $skins_skinsets = skinr_skinsets('skinset'); $themes_skinsets = skinr_skinsets('theme'); // Need to merge all skins skinsets into a single list of skins. // Also merge in the groups information. $additional_skins = array(); $groups = array(); foreach ($skins_skinsets as $key => $skinset) { if (!empty($skinset->skins) && $skinset->status == 1) { $additional_skins += $skinset->skins; } if (!empty($skinset->options['groups'])) { $groups += $skinset->options['groups']; } } // Merge the additional skins into each theme, even if that theme has no // skinr data. $themes = list_themes(); foreach ($themes as $theme) { if ($theme->status != 1) { continue; } if (isset($themes_skinsets[$theme->name])) { $cache[$theme->name] = $themes_skinsets[$theme->name]; $cache[$theme->name]->skins += $additional_skins; $cache[$theme->name]->options['groups'] += $groups; } else { $cache[$theme->name] = array( 'options' => array('groups' => $groups), 'skins' => $additional_skins, ); } } } return $cache; } /** * Fetch Skinr configuration data from modules. */ function skinr_fetch_config() { static $cache = NULL; if (is_null($cache)) { $cache = module_invoke_all('skinr_config'); foreach (module_implements('skinr_config_alter') as $module) { $function = $module .'_skinr_config_alter'; $function($cache); } } return $cache; } /** * Fetch default configuration data for modules. */ function _skinr_fetch_config_defaults($setting) { switch ($setting) { case 'form': $data = array( 'access_handler' => 'skinr_access_handler', 'data_handler' => 'skinr_data_handler', 'submit_handler' => 'skinr_submit_handler', 'submit_handler_attach_to' => array('#submit'), 'skinr_title' => t('Skinr'), 'skinr_weight' => 1, 'title' => '', 'description' => t('Manage which skins you want to apply to the hooks'), 'collapsed' => TRUE, 'weight' => 0, ); return $data; } } /** * Execute a module's data handler. */ function skinr_handler($type, $op, $handler, &$a3, $a4 = NULL, $a5 = NULL, $a6 = NULL, $a7 = NULL) { if (is_callable($handler)) { switch ($type) { case 'preprocess_index_handler': return $handler($a3); case 'preprocess_hook_callback': return $handler($a3, $a4); case 'data_handler': case 'submit_handler': return $handler($a3, $a4, $a5, $a6, $a7); default: return $handler($op, $a3, $a4); } } }