You are here

skinr.module in Skinr 6

Same filename and directory in other branches
  1. 8.2 skinr.module
  2. 6.2 skinr.module
  3. 7.2 skinr.module

File

skinr.module
View source
<?php

/**
 * Implementation of hook_perm().
 */
function skinr_perm() {
  return array(
    'access skinr',
    'access skinr classes',
    'administer skinr',
  );
}

/**
 * Implementation of hook_menu().
 */
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;
}

/**
 * Implementation of hook_help().
 */
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;
  }
}

/**
 * Implementation of hook_init().
 */
function skinr_init() {
  static $run = FALSE;
  if (!$run) {
    skinr_include('handlers');
    skinr_module_include('skinr.inc');
    $run = TRUE;
  }
}

/**
 * Implementation of hook_form_alter().
 */
function skinr_form_alter(&$form, $form_state, $form_id) {

  // Fix for update script.
  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]);

      // Check for access.
      if (!skinr_handler('access_handler', 'access skinr', $form_settings['access_handler'], $form, $form_state)) {

        // Deny access.
        break;
      }

      // Ensure we have the required preprocess_hook or preprocess_hook_callback.
      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);

      // There's a bug that sometimes disables all themes. This will check for
      // the bug in question. http://drupal.org/node/305653
      $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 {

          // Handle preview before submit.
          $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;
        }

        // Create individual widgets for each skin.
        $template_options = array();
        if (isset($info[$theme->name]['skins'])) {
          foreach ($info[$theme->name]['skins'] as $skin_id => $skin) {

            // Check if this skin applies to this hook.
            if (!is_array($skin['features']) || !in_array('*', $skin['features']) && !in_array($preprocess_hook, $skin['features'])) {
              continue;
            }

            // Create widget.
            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(
                    '' => '&lt;none&gt;',
                  ), 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;
            }

            // Prepare templates.
            $templates = skinr_info_templates_filter($skin['templates'], $preprocess_hook);
            $template_options = array_merge($template_options, skinr_info_templates_to_form_options($templates));
          }
        }

        // Check for access.
        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,
            )),
          );

          // Only add validation handler once.
          if (!in_array('skinr_form_validate', $form['#validate'])) {
            $form['#validate'][] = 'skinr_form_validate';
          }

          // Special for views.
          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);
      }

      // Only add submit handler once.
      if (is_string($form_settings['submit_handler_attach_to'])) {

        // Backwards compatibility with previous versions
        $form_settings['submit_handler_attach_to'] = explode('][', preg_replace('/(^\\[|\\]$|\'|")/', '', $form_settings['submit_handler_attach_to']));
      }

      // Find the property to check.
      $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';
      }

      // Keep looping, there might be other modules that implement the same form_id.
    }
  }
}

/**
 * Validation handler.
 */
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]);

          // Validate additional classes field.
          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 _.'));
          }

          // Keep looping, there might be other modules that implement the same form_id.
        }
      }
    }
  }
}

/**
 * Submit handler.
 */
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);

      // Keep looping, there might be other modules that implement the same form_id.
    }
  }
}

/**
 * Implementation of hook_preprocess().
 */
function skinr_preprocess(&$vars, $hook) {

  // Fix for update script.
  if (defined('MAINTENANCE_MODE')) {
    return;
  }
  static $data = NULL;

  // Caching the data returned from the following functions is reported to
  // improve performance.
  if (is_null($data)) {

    // 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();
    $data['current_theme'] = skinr_current_theme();
    $data['skinr_data'] = skinr_fetch_data();
    $data['info'] = skinr_process_info_files();
    $data['theme_registry'] = theme_get_registry();
  }

  // Add any base themes if they exist for the current theme.
  $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']));
  }

  // Add the 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) {

          // Add custom CSS files.
          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);
              }
            }
          }

          // Add custom JS files.
          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');
            }
          }
        }

        // Add template files.
        if (!empty($style['_template'])) {
          $vars['template_files'][] = $style['_template'];
          unset($style['_template']);
        }
        $vars['skinr'] = skinr_style_array_to_string($style);
      }
    }
  }
}

/**
 * Helper function 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, $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;
    }
  }
}

/**
 * Helper function to convert an array of classes settings into a string, usable
 * in HTML.
 */
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);
}

// ------------------------------------------------------------------
// Include file helpers.

/**
 * Include skinr .inc files as necessary.
 */
function skinr_include($file) {
  require_once './' . drupal_get_path('module', 'skinr') . "/includes/{$file}.inc";
}

/**
 * Load views 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.0) {
        if (!isset($info['path'])) {
          $info['path'] = drupal_get_path('module', $module);
        }
        $cache[$module] = $info;
      }
    }
  }
  return $cache;
}

// -----------------------------------------------------------------------
// Skinr data handling functions.

/**
 * Save an entry to Skinr.
 */
function skinr_set($theme, $module, $key, $value) {
  $skinr = variable_get('skinr_' . $theme, array());

  // Make sure we're getting valid data.
  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);
}

/**
 * Retrieves the desired classes.
 * If no hook or key are specified, it will return all skinr classes.
 *
 * @return
 *   An array.
 */
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();
  }
}

/**
 * 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 $exclude_admin_theme
 *   Optional. Set to TRUE to exclude the admin theme from possible 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;
}

/**
 * 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) {
  $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;
}

/**
 * Themes are allowed to set Skinr styles in their .info files.
 *
 * @todo Do we want to allow manual addition of styles?
 * @todo Use DB caching. No need to keep processing things every page load.
 */
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'];

        // Store skinr options.
        if (!empty($info['options'])) {
          $cache[$theme->name]['options'] = $info['options'];
          unset($info['options']);
        }

        // Inherit skins from parent theme, if inherit_skins is set to true.
        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;
}

/**
 * Helper function to convert an array of options, as specified in the info
 * file, into an array usable by form api.
 */
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;
}

/**
 * Helper function to convert an array of template filenames, as specified in
 * the info file, into an array usable by form api.
 */
function skinr_info_templates_to_form_options($templates) {
  $form_options = array();
  foreach ($templates as $template) {

    // If it exists, strip .tpl.php from template.
    $template = str_replace('.tpl.php', '', $template);
    $form_options[$template] = $template . '.tpl.php';
  }
  return $form_options;
}

/**
 * Helper function to filter templates by preprocess_hook.
 */
function skinr_info_templates_filter($templates, $preprocess_hook) {
  $filtered_templates = array();
  foreach ($templates as $template) {

    // If it exists, strip .tpl.php from 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;
}

/**
 * Fetch Skinr configuration data from modules.
 */
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;
}

/**
 * Fetch default configuration data for modules.
 */
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;
  }
}

/**
 * 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);
    }
  }
}

Functions

Namesort descending Description
skinr_current_theme Helper function to retrieve the current theme. The global variable $theme_key doesn't work for our purposes when an admin theme is enabled.
skinr_fetch_data Fetch Skinr configuration data from modules.
skinr_form_alter Implementation of hook_form_alter().
skinr_form_submit Submit handler.
skinr_form_validate Validation handler.
skinr_get Retrieves the desired classes. If no hook or key are specified, it will return all skinr classes.
skinr_get_module_apis Get a list of modules that support skinr.
skinr_handler Execute a module's data handler.
skinr_help Implementation of hook_help().
skinr_include Include skinr .inc files as necessary.
skinr_info_options_to_form_options Helper function to convert an array of options, as specified in the info file, into an array usable by form api.
skinr_info_templates_filter Helper function to filter templates by preprocess_hook.
skinr_info_templates_to_form_options Helper function to convert an array of template filenames, as specified in the info file, into an array usable by form api.
skinr_inherited_skins Retrieves all the Skinr skins from theme parents. Theme skins will override any skins of the same name from its parents.
skinr_init Implementation of hook_init().
skinr_menu Implementation of hook_menu().
skinr_module_include Load views files on behalf of modules.
skinr_perm Implementation of hook_perm().
skinr_preprocess Implementation of hook_preprocess().
skinr_process_info_files Themes are allowed to set Skinr styles in their .info files.
skinr_set Save an entry to Skinr.
skinr_style_array_to_string Helper function to convert an array of classes settings into a string, usable in HTML.
_skinr_add_file Helper function to add CSS and JS files.
_skinr_fetch_data_defaults Fetch default configuration data for modules.