View source
<?php
function skinr_perm() {
return array(
'access skinr',
'access skinr classes',
'administer skinr',
);
}
function skinr_menu() {
$items['admin/settings/skinr'] = array(
'title' => 'Skinr',
'page callback' => 'skinr_admin',
'access arguments' => array(
'administer skinr',
),
'file' => 'skinr.admin.inc',
);
$items['admin/settings/skinr/settings'] = array(
'title' => 'Settings',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/settings/skinr/import'] = array(
'title' => 'Import',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'skinr_import_form',
),
'type' => MENU_LOCAL_TASK,
'access arguments' => array(
'administer skinr',
),
'parent' => 'admin/settings/skinr',
'weight' => 1,
'file' => 'skinr.admin.inc',
);
$items['admin/settings/skinr/export'] = array(
'title' => 'Export',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'skinr_export_form',
),
'type' => MENU_LOCAL_TASK,
'access arguments' => array(
'administer skinr',
),
'parent' => 'admin/settings/skinr',
'weight' => 2,
'file' => 'skinr.admin.inc',
);
return $items;
}
function skinr_help($path, $arg) {
switch ($path) {
case 'admin/help#skinr':
return t('Please refer to <a class="ext" href="http://drupal.org/node/578552">@skinr introduction </a> and <a class="ext" href="http://drupal.org/node/578574">documentation</a>.', array(
'@skinr' => 'Skinr',
));
break;
case 'admin/settings/skinr':
return t('Please refer to <a class="ext" href="http://drupal.org/node/578552">@skinr introduction </a> and <a class="ext" href="http://drupal.org/node/578574">documentation</a>.', array(
'@skinr' => 'Skinr',
));
break;
}
}
function skinr_init() {
static $run = FALSE;
if (!$run) {
skinr_include('handlers');
skinr_module_include('skinr.inc');
$run = TRUE;
}
}
function skinr_form_alter(&$form, $form_state, $form_id) {
if (defined('MAINTENANCE_MODE')) {
return;
}
$skinr_data = skinr_fetch_data();
$info = skinr_process_info_files();
foreach ($skinr_data as $module => $settings) {
if (isset($settings['form'][$form_id])) {
$form_settings = array_merge(_skinr_fetch_data_defaults('form'), $settings['form'][$form_id]);
if (!skinr_handler('access_handler', 'access skinr', $form_settings['access_handler'], $form, $form_state)) {
break;
}
if (empty($form_settings['preprocess_hook']) && empty($form_settings['preprocess_hook_callback'])) {
trigger_error(sprintf("No preprocess_hook or preprocess_hook_callback was found for form_id '%s' in module '%s'.", $form_id, $module), E_USER_ERROR);
}
$themes = list_themes();
ksort($themes);
$enabled_themes = 0;
foreach ($themes as $theme) {
if (!$theme->status) {
continue;
}
$enabled_themes++;
$preprocess_hook = !empty($form_settings['preprocess_hook']) ? $form_settings['preprocess_hook'] : skinr_handler('preprocess_hook_callback', '', $form_settings['preprocess_hook_callback'], $form, $form_state);
if (!$form_state['submitted']) {
$skinr_data = skinr_handler('data_handler', 'form', $form_settings['data_handler'], $form, $form_state, $theme->name, $module, $form_settings);
$defaults = $skinr_data;
$additional_default = isset($skinr_data['_additional']) ? $skinr_data['_additional'] : '';
$template_default = isset($skinr_data['_template']) ? $skinr_data['_template'] : '';
}
else {
$defaults = $form_state['values']['widgets'];
$additional_default = $form_state['values']['_additional'];
$template_default = $form_state['values']['_template'];
}
if (!isset($form['skinr_settings'])) {
$form['skinr_settings'] = array(
'#tree' => TRUE,
'#weight' => $form_settings['skinr_weight'],
);
}
if (!isset($form['skinr_settings'][$module . '_group'])) {
$form['skinr_settings'][$module . '_group'] = array(
'#type' => 'fieldset',
'#title' => t('@skinr_title @title', array(
'@skinr_title' => $form_settings['skinr_title'],
'@title' => $form_settings['title'],
)),
'#description' => t($form_settings['description']) . ' <strong>' . $preprocess_hook . '</strong>.',
'#weight' => $form_settings['weight'],
'#collapsible' => TRUE,
'#collapsed' => $form_settings['collapsed'],
);
}
$form['skinr_settings'][$module . '_group'][$theme->name] = array(
'#type' => 'fieldset',
'#title' => $theme->info['name'] . ($theme->name == skinr_current_theme() ? ' (' . t('enabled + default') . ')' : ''),
'#collapsible' => TRUE,
'#collapsed' => $theme->name == skinr_current_theme() ? FALSE : TRUE,
);
if ($theme->name == skinr_current_theme()) {
$form['skinr_settings'][$module . '_group'][$theme->name]['#weight'] = -10;
}
$template_options = array();
if (isset($info[$theme->name]['skins'])) {
foreach ($info[$theme->name]['skins'] as $skin_id => $skin) {
if (!is_array($skin['features']) || !in_array('*', $skin['features']) && !in_array($preprocess_hook, $skin['features'])) {
continue;
}
switch ($skin['type']) {
case 'checkboxes':
$form['skinr_settings'][$module . '_group'][$theme->name]['widgets'][$skin_id] = array(
'#type' => 'checkboxes',
'#multiple' => TRUE,
'#title' => t($skin['title']),
'#options' => skinr_info_options_to_form_options($skin['options']),
'#default_value' => isset($defaults[$skin_id]) ? $defaults[$skin_id] : array(),
'#description' => t($skin['description']),
'#weight' => isset($skin['weight']) ? $skin['weight'] : NULL,
);
break;
case 'radios':
$form['skinr_settings'][$module . '_group'][$theme->name]['widgets'][$skin_id] = array(
'#type' => 'radios',
'#title' => t($skin['title']),
'#options' => array_merge(array(
'' => '<none>',
), skinr_info_options_to_form_options($skin['options'])),
'#default_value' => isset($defaults[$skin_id]) ? $defaults[$skin_id] : '',
'#description' => t($skin['description']),
'#weight' => isset($skin['weight']) ? $skin['weight'] : NULL,
);
break;
case 'select':
$form['skinr_settings'][$module . '_group'][$theme->name]['widgets'][$skin_id] = array(
'#type' => 'select',
'#title' => t($skin['title']),
'#options' => array_merge(array(
'' => '<none>',
), skinr_info_options_to_form_options($skin['options'])),
'#default_value' => isset($defaults[$skin_id]) ? $defaults[$skin_id] : '',
'#description' => t($skin['description']),
'#weight' => isset($skin['weight']) ? $skin['weight'] : NULL,
);
break;
}
$templates = skinr_info_templates_filter($skin['templates'], $preprocess_hook);
$template_options = array_merge($template_options, skinr_info_templates_to_form_options($templates));
}
}
if (skinr_handler('access_handler', 'access skinr classes', $form_settings['access_handler'], $form, $form_state)) {
$form['skinr_settings'][$module . '_group'][$theme->name]['advanced'] = array(
'#type' => 'fieldset',
'#title' => t('Advanced options'),
'#collapsible' => TRUE,
'#collapsed' => empty($additional_default),
);
$form['skinr_settings'][$module . '_group'][$theme->name]['advanced']['_additional'] = array(
'#type' => 'textfield',
'#title' => t('Apply additional CSS classes'),
'#description' => t('Optionally add additional CSS classes. Example: <em>my-first-class my-second-class</em>'),
'#default_value' => $additional_default,
);
$form['skinr_settings'][$module . '_group'][$theme->name]['advanced']['_template'] = array(
'#type' => 'select',
'#title' => t('Template file'),
'#options' => array_merge(array(
'' => 'Default',
), $template_options),
'#default_value' => $template_default,
'#description' => t('Optionally, select a template file to associate with this <strong>!hook</strong>. Selecting "Default" will let Drupal handle this.', array(
'!hook' => $preprocess_hook,
)),
);
if (!in_array('skinr_form_validate', $form['#validate'])) {
$form['#validate'][] = 'skinr_form_validate';
}
if (isset($form['buttons']['submit']['#validate']) && !in_array('skinr_form_validate', $form['buttons']['submit']['#validate'])) {
$form['buttons']['submit']['#validate'][] = 'skinr_form_validate';
}
}
}
if ($enabled_themes == 0) {
drupal_set_message(t('Skinr has detected that none of your themes are enabled. This is likely related the Drupal bug: <a href="http://drupal.org/node/305653">Themes disabled during update</a>. Please re-enable your theme to continue using Skinr.'), 'warning', FALSE);
}
if (is_string($form_settings['submit_handler_attach_to'])) {
$form_settings['submit_handler_attach_to'] = explode('][', preg_replace('/(^\\[|\\]$|\'|")/', '', $form_settings['submit_handler_attach_to']));
}
$attr =& $form;
foreach ($form_settings['submit_handler_attach_to'] as $part) {
$attr =& $attr[$part];
}
if (!empty($attr) && !in_array('skinr_form_submit', $attr)) {
$string = $attr[] = 'skinr_form_submit';
}
}
}
}
function skinr_form_validate(&$form, &$form_state) {
$form_id = $form_state['values']['form_id'];
$skinr_data = skinr_fetch_data();
foreach ($skinr_data as $module => $settings) {
if (isset($settings['form'][$form_id]) && isset($form_state['values']['skinr_settings'][$module . '_group'])) {
foreach ($form_state['values']['skinr_settings'][$module . '_group'] as $theme_name => $theme) {
if (isset($theme['advanced']['_additional'])) {
$form_settings = array_merge(_skinr_fetch_data_defaults('form'), $settings['form'][$form_id]);
if (preg_match('/[^a-zA-Z0-9\\-\\_\\s]/', $theme['advanced']['_additional'])) {
form_set_error('skinr_settings][' . $module . '_group][' . $theme_name . '][advanced][_additional', t('Additional classes for Skinr may only contain alphanumeric characters, spaces, - and _.'));
}
}
}
}
}
}
function skinr_form_submit(&$form, &$form_state) {
$form_id = $form_state['values']['form_id'];
$skinr_data = skinr_fetch_data();
foreach ($skinr_data as $module => $settings) {
if (isset($settings['form'][$form_id])) {
$form_settings = array_merge(_skinr_fetch_data_defaults('form'), $settings['form'][$form_id]);
skinr_handler('submit_handler', '', $form_settings['submit_handler'], $form, $form_state, $module, $form_settings);
}
}
}
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_data'] = skinr_fetch_data();
$data['info'] = skinr_process_info_files();
$data['theme_registry'] = theme_get_registry();
}
$theme_list = list_themes();
$themes = array();
if (isset($theme_list[$data['current_theme']]->info['base theme'])) {
$themes = array_keys(system_find_base_themes($theme_list, $data['current_theme']));
}
$themes[] = $data['current_theme'];
$original_hook = $hook;
if (isset($data['theme_registry'][$hook]['original hook'])) {
$original_hook = $data['theme_registry'][$hook]['original hook'];
}
$vars['skinr'] = '';
foreach ($data['skinr_data'] as $module => $settings) {
if (!empty($settings['preprocess'][$original_hook])) {
$preprocess_settings = $settings['preprocess'][$original_hook];
$key = skinr_handler('preprocess_index_handler', 'preprocess', $preprocess_settings['index_handler'], $vars);
if (!empty($key)) {
if (is_array($key)) {
$style = array();
foreach ($key as $keykey) {
$style = skinr_get(NULL, $module, $keykey) + $style;
}
}
else {
$style = skinr_get(NULL, $module, $key);
}
foreach ($style as $skin => $classes) {
if (!empty($data['info'][$data['current_theme']]['skins'][$skin]['stylesheets'])) {
foreach ($data['info'][$data['current_theme']]['skins'][$skin]['stylesheets'] as $media => $stylesheets) {
foreach ($stylesheets as $stylesheet) {
_skinr_add_file($stylesheet, $themes, 'css', $media);
}
}
}
if (isset($data['info'][$data['current_theme']]['skins'][$skin]['scripts'])) {
foreach ($data['info'][$data['current_theme']]['skins'][$skin]['scripts'] as $script) {
_skinr_add_file($script, $themes, 'js');
}
}
}
if (!empty($style['_template'])) {
$vars['template_files'][] = $style['_template'];
unset($style['_template']);
}
$vars['skinr'] = skinr_style_array_to_string($style);
}
}
}
}
function _skinr_add_file($filename, $themes, $type, $media = NULL) {
if (!is_array($themes)) {
$themes = array(
$themes,
);
}
foreach ($themes as $theme) {
$file = drupal_get_path('theme', $theme) . '/' . $filename;
if (file_exists($file)) {
if ($type == 'css') {
drupal_add_css($file, 'theme', $media);
}
else {
drupal_add_js($file, 'theme');
}
break;
}
}
}
function skinr_style_array_to_string($style) {
$return = array();
foreach ($style 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 implode(' ', $return);
}
function skinr_include($file) {
require_once './' . drupal_get_path('module', 'skinr') . "/includes/{$file}.inc";
}
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_set($theme, $module, $key, $value) {
$skinr = variable_get('skinr_' . $theme, array());
if (empty($module) || empty($key)) {
return;
}
if (!$value && isset($skinr[$module][$key])) {
unset($skinr[$module][$key]);
}
else {
if (!isset($skinr[$module])) {
$skinr[$module] = array();
}
$skinr[$module][$key] = $value;
}
variable_set('skinr_' . $theme, $skinr);
}
function skinr_get($theme = NULL, $module = NULL, $key = NULL) {
if (is_null($theme)) {
$theme = skinr_current_theme();
}
$skinr = variable_get('skinr_' . $theme, array());
if (is_null($module) || is_null($key)) {
return $skinr;
}
elseif (isset($skinr[$module][$key])) {
return $skinr[$module][$key];
}
else {
return 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_inherited_skins($theme, $themes) {
$all_skins = $skins = array();
$base_theme = !empty($themes[$theme]->info['base theme']) ? $themes[$theme]->info['base theme'] : '';
while ($base_theme) {
$all_skins[] = !empty($themes[$base_theme]->info['skinr']) ? (array) $themes[$base_theme]->info['skinr'] : array();
$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_process_info_files() {
static $cache = NULL;
if (is_null($cache)) {
$themes = list_themes();
foreach ($themes as $theme) {
$cache[$theme->name] = array(
'options' => array(),
'skins' => array(),
);
if (!empty($theme->info['skinr'])) {
$info = (array) $theme->info['skinr'];
if (!empty($info['options'])) {
$cache[$theme->name]['options'] = $info['options'];
unset($info['options']);
}
if (!empty($cache[$theme->name]['options']['inherit_skins'])) {
$info = array_merge(skinr_inherited_skins($theme->name, $themes), $info);
}
foreach ($info as $id => $skin) {
$processed_skin = array(
'title' => isset($skin['title']) ? $skin['title'] : '',
'type' => isset($skin['type']) ? $skin['type'] : 'checkboxes',
'description' => isset($skin['description']) ? $skin['description'] : '',
'weight' => isset($skin['weight']) ? $skin['weight'] : NULL,
'features' => isset($skin['features']) ? $skin['features'] : array(
'*',
),
'templates' => isset($skin['templates']) ? $skin['templates'] : array(),
'options' => isset($skin['options']) ? $skin['options'] : array(),
'stylesheets' => isset($skin['stylesheets']) ? $skin['stylesheets'] : array(),
'scripts' => isset($skin['scripts']) ? $skin['scripts'] : array(),
);
$cache[$theme->name]['skins'][$id] = $processed_skin;
}
}
}
}
return $cache;
}
function skinr_info_options_to_form_options($options) {
$form_options = array();
foreach ($options as $option) {
$form_options[$option['class']] = t($option['label']);
}
return $form_options;
}
function skinr_info_templates_to_form_options($templates) {
$form_options = array();
foreach ($templates as $template) {
$template = str_replace('.tpl.php', '', $template);
$form_options[$template] = $template . '.tpl.php';
}
return $form_options;
}
function skinr_info_templates_filter($templates, $preprocess_hook) {
$filtered_templates = array();
foreach ($templates as $template) {
$template = str_replace('.tpl.php', '', $template);
if (drupal_substr(str_replace('_', '-', $template), drupal_strlen($preprocess_hook) * -1) == str_replace('_', '-', $preprocess_hook)) {
$filtered_templates[] = $template;
}
}
return $filtered_templates;
}
function skinr_fetch_data() {
static $cache = NULL;
if (is_null($cache)) {
$cache = module_invoke_all('skinr_data');
foreach (module_implements('skinr_data_alter') as $module) {
$function = $module . '_skinr_data_alter';
$function($cache);
}
}
return $cache;
}
function _skinr_fetch_data_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 this'),
'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);
}
}
}