View source
<?php
function skinr_help($path, $arg) {
switch ($path) {
case 'admin/help#skinr':
if (module_exists('advanced_help')) {
return t('Visit the <a href="@skinr-help">help page</a> for full documentation.', array(
'@skinr-help' => url('admin/advanced_help/skinr'),
));
}
else {
return t('Please download and enable the <a href="http://drupal.org/project/advanced_help">Advanced Help</a> module for full Skinr documentation.');
}
break;
}
}
function skinr_init() {
static $run = FALSE;
if (!$run) {
module_load_include('inc', 'skinr', 'skinr.handlers');
skinr_module_include('skinr.inc');
$run = TRUE;
}
}
function skinr_preprocess(&$vars, $hook) {
if (defined('MAINTENANCE_MODE')) {
return;
}
static $data = NULL;
if (is_null($data)) {
skinr_init();
$data['current_theme'] = skinr_current_theme();
$data['skinr_config'] = skinr_fetch_config();
$data['theme_registry'] = theme_get_registry();
}
$original_hook = $hook;
if (isset($data['theme_registry'][$hook]['original hook'])) {
$original_hook = $data['theme_registry'][$hook]['original hook'];
}
foreach ($data['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, $data['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'];
$context = array(
'hook' => $hook,
'vars' => &$vars,
'skin' => &$extracted,
);
drupal_alter('skinr_preprocess', $context);
$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;
}
$reset = FALSE;
}
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);
if (!empty($skins['_template'])) {
$extracted['template'] = $skins['_template'];
unset($skins['_template']);
}
$extracted['classes'] = skinr_flatten_skins_array($skins);
return $extracted;
}
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) {
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) {
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;
}
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');
}
}
}
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;
}
function skinr_rule_save($rule) {
drupal_write_record('skinr_rules', $rule, !empty($rule->rid) ? array(
'rid',
) : array());
}
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;
}
}
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;
}
if ($rule->pages) {
if ($rule->visibility < 2) {
$path = drupal_get_path_alias($_GET['q']);
$page_match = drupal_match_path($path, $rule->pages);
if ($path != $_GET['q']) {
$page_match = $page_match || drupal_match_path($_GET['q'], $rule->pages);
}
$page_match = !($rule->visibility xor $page_match);
}
else {
$page_match = drupal_eval($rule->pages);
}
}
return $page_match;
}
return FALSE;
}
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}";
}
}
}
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.0) {
if (!isset($info['path'])) {
$info['path'] = drupal_get_path('module', $module);
}
$cache[$module] = $info;
}
}
}
return $cache;
}
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;
}
$skinr->skins = _skinr_array_strip_empty($skinr->skins);
return TRUE;
}
function skinr_set($skinr) {
if (!skinr_validate($skinr)) {
return FALSE;
}
if (empty($skinr->skins) && empty($skinr->settings)) {
db_query("DELETE FROM {skinr} WHERE theme = '%s' AND module = '%s' AND sid = '%s'", $skinr->theme, $skinr->module, $skinr->sid);
}
else {
if (skinr_get($skinr->theme, $skinr->module, $skinr->sid) !== FALSE) {
drupal_write_record('skinr', $skinr, array(
'theme',
'module',
'sid',
));
}
else {
drupal_write_record('skinr', $skinr);
}
}
return TRUE;
}
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)) {
$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)) {
$result = db_query("SELECT theme, module, sid, settings, skins FROM {skinr} WHERE theme = '%s' AND module = '%s'", $theme, $module);
}
else {
$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)) {
if (isset($cache[$theme])) {
return $cache[$theme];
}
}
elseif (is_null($sid)) {
if (isset($cache[$theme][$module])) {
return $cache[$theme][$module];
}
}
elseif (isset($cache[$theme][$module][$sid])) {
return $cache[$theme][$module][$sid];
}
return FALSE;
}
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;
}
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'))) {
$current_theme = $custom_theme;
}
else {
$current_theme = variable_get('theme_default', 'garland');
}
return $current_theme;
}
function skinr_skins_default() {
return array(
'description' => '',
'screenshot' => 'screenshot.png',
'php' => DRUPAL_MINIMUM_PHP,
'skinr' => array(),
);
}
function skinr_group_default() {
return array(
'title' => '',
'description' => '',
'collapsible' => TRUE,
'collapsed' => FALSE,
'weight' => NULL,
);
}
function skinr_skin_default() {
return array(
'title' => '',
'type' => 'checkboxes',
'description' => '',
'features' => array(
'*',
),
'templates' => array(),
'group' => '',
'options' => array(),
'stylesheets' => array(),
'scripts' => array(),
'weight' => NULL,
);
}
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) {
$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;
}
function _skinr_skins_data() {
static $skins_info = array();
if (empty($skins_info)) {
$mask = '\\.info$';
$directory = 'skins';
$skinsets = drupal_system_listing($mask, $directory);
$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));
}
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;
if (!empty($skinsets[$key]->info['screenshot'])) {
$skinsets[$key]->info['screenshot'] = dirname($skinsets[$key]->filename) . '/' . $skinsets[$key]->info['screenshot'];
}
drupal_alter('skinr_info', $skinsets[$key]->info, $skinsets[$key]);
}
$skins_info = $skinsets;
}
return $skins_info;
}
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'];
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'];
}
}
_skinr_add_paths_to_files($skinr_info, $path_root);
if (!empty($skinset['options']['inherit_skins'])) {
$base_info = skinr_inherited_skins($info->name);
$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;
}
if (!empty($skin['stylesheets'])) {
$skinr_info[$id]['stylesheets'] = _skinr_add_path_to_files($skin['stylesheets'], $path_root, 'css');
}
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');
}
}
}
}
}
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;
}
function skinr_skinsets($type, $refresh = FALSE) {
if (defined('MAINTENANCE_MODE')) {
return array();
}
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') {
if (variable_get('skinr_rebuild_skinset_data', FALSE)) {
skinr_rebuild_skinset_data();
}
$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];
}
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];
}
function skinr_rebuild_skinset_data() {
if (defined('MAINTENANCE_MODE')) {
return array();
}
$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));
}
variable_set('skinr_rebuild_skinset_data', FALSE);
return $skinsets;
}
function skinr_flush_caches() {
variable_set('skinr_rebuild_skinset_data', TRUE);
return array();
}
function skinr_get_files_database(&$files) {
$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;
}
}
}
}
}
function skinr_skin_data() {
static $cache = NULL;
if (is_null($cache)) {
$skins_skinsets = skinr_skinsets('skinset');
$themes_skinsets = skinr_skinsets('theme');
$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'];
}
}
$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;
}
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;
}
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;
}
}
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);
}
}
}