You are here

skinr_context_ui.module in Skinr 8.2

Same filename and directory in other branches
  1. 7.2 skinr_context/skinr_context_ui.module

Administrative interface for Skinr Context. Without this module, you cannot edit your skins with context.

File

skinr_context/skinr_context_ui.module
View source
<?php

/**
 * @file
 * Administrative interface for Skinr Context. Without this module, you cannot edit your skins with context.
 */

/**
 * Implements hook_menu().
 */
function skinr_context_ui_menu() {

  // Administration.
  $items['admin/structure/skinr/list/skins'] = array(
    'title' => 'Skins',
    'description' => t('Manage skin configurations.'),
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -10,
  );
  $items['admin/structure/skinr/list/groups'] = array(
    'title' => 'Groups',
    'description' => t('Manage skin configuration groups.'),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'skinr_context_ui_admin_list',
    ),
    'access arguments' => array(
      'administer skinr',
    ),
    'type' => MENU_LOCAL_TASK,
    'file' => 'skinr_context_ui.admin.inc',
  );

  // Configure skin configuration group for an element.
  $items['admin/structure/skinr/edit/%/%/%skinr_context_group'] = array(
    'title' => 'Edit skin',
    'title callback' => 'skinr_context_ui_edit_title',
    'title arguments' => array(
      4,
      5,
      6,
    ),
    'page callback' => 'skinr_context_ui_edit',
    'page arguments' => array(
      4,
      5,
      6,
    ),
    // module, element, gid
    'type' => MENU_LOCAL_TASK,
    'access arguments' => array(
      'edit skin settings',
    ),
    'file' => 'skinr_context_ui.edit.inc',
  );

  // Add skin configuration group to an element.
  $items['admin/structure/skinr/edit/%/%/add'] = array(
    'title' => 'Add group',
    'page callback' => 'skinr_context_ui_group_add',
    'page arguments' => array(
      4,
      5,
    ),
    // module, element
    'type' => MENU_LOCAL_ACTION,
    'access arguments' => array(
      'edit skin settings',
    ),
    'file' => 'skinr_context_ui.edit.inc',
  );

  // Enable a skin configuration group.
  $items['admin/structure/skinr/group/%skinr_context_group/enable'] = array(
    'title' => 'Enable group',
    'page callback' => 'skinr_context_ui_group_status_set',
    'page arguments' => array(
      4,
      TRUE,
    ),
    'type' => MENU_CALLBACK,
    'access arguments' => array(
      'administer skinr',
    ),
    'file' => 'skinr_context_ui.admin.inc',
  );

  // Disable a skin configuration group.
  $items['admin/structure/skinr/group/%skinr_context_group/disable'] = array(
    'title' => 'Disable group',
    'page callback' => 'skinr_context_ui_group_status_set',
    'page arguments' => array(
      4,
      FALSE,
    ),
    'type' => MENU_CALLBACK,
    'access arguments' => array(
      'administer skinr',
    ),
    'file' => 'skinr_context_ui.admin.inc',
  );

  // Revert a skin configuration group.
  $items['admin/structure/skinr/group/%skinr_context_group/revert'] = array(
    'title' => 'Revert group',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'skinr_context_ui_revert_confirm',
      4,
    ),
    'type' => MENU_CALLBACK,
    'access arguments' => array(
      'administer skinr',
    ),
    'file' => 'skinr_context_ui.admin.inc',
  );

  // Delete a skin configuration group.
  $items['admin/structure/skinr/edit/%/%/%skinr_context_group/delete'] = array(
    'title' => 'Delete group',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'skinr_context_ui_group_delete_confirm',
      6,
    ),
    'type' => MENU_CALLBACK,
    'access arguments' => array(
      'edit skin settings',
    ),
    'file' => 'skinr_context_ui.edit.inc',
  );
  return $items;
}

/**
 * Implements hook_menu_alter().
 */
function skinr_context_ui_menu_alter(&$items) {
  $items['admin/structure/skinr/edit/%/%']['page callback'] = 'skinr_context_ui_group_list';
  $items['admin/structure/skinr/edit/%/%']['file'] = 'skinr_context_ui.edit.inc';
  $items['admin/structure/skinr/edit/%/%']['file path'] = drupal_get_path('module', 'skinr_context_ui');
  $items['admin/structure/skinr']['page arguments'] = array(
    'skinr_context_ui_admin_skin_list',
  );
  $items['admin/structure/skinr']['file'] = 'skinr_context_ui.admin.inc';
  $items['admin/structure/skinr']['file path'] = drupal_get_path('module', 'skinr_context_ui');
}

/**
 * Implements hook_menu_local_tasks_alter().
 */
function skinr_context_ui_menu_local_tasks_alter(&$data, $router_item, $root_path) {
  $destination = array();
  if (isset($_GET['destination'])) {
    $path = $_GET['q'];
    $query = drupal_http_build_query(drupal_get_query_parameters());
    if ($query != '') {
      $path .= '?' . $query;
    }
    $destination = array(
      'destination' => $path,
    );
  }
  if ($destination && $root_path == 'admin/structure/skinr/edit/%/%') {
    foreach ($data['actions']['output'] as $key => $item) {
      if ($item['#link']['path'] == 'admin/structure/skinr/edit/%/%/add') {

        // Add destination query string to link to preserve it.
        if (empty($data['actions']['output'][$key]['#link']['localized_options']['query'])) {
          $data['actions']['output'][$key]['#link']['localized_options']['query'] = array();
        }
        $data['actions']['output'][$key]['#link']['localized_options']['query'] += $destination;
      }
    }
  }
}

/**
 * Menu title callback; sets the title for a skins configuration form page.
 *
 * @param $module
 *   The module that we're editing settings of.
 * @param $element
 *   The element we're editing settings of.
 */
function skinr_context_ui_edit_title($module, $element, $group) {
  return t('Skin settings for !group group (!module type !element)', array(
    '!group' => $group->title,
    '!module' => $module,
    '!element' => $element,
  ));
}

/**
 * Implements hook_theme().
 */
function skinr_context_ui_theme() {
  $items['skinr_context_ui_group_list_form'] = array(
    'render element' => 'form',
    'file' => 'skinr_context_ui.edit.inc',
  );
  $items['skinr_context_ui_group_summary'] = array(
    'variables' => array(
      'title' => NULL,
      'description' => NULL,
    ),
    'file' => 'skinr_context_ui.edit.inc',
  );
  return $items;
}

/**
 * Implements hook_help().
 */
function skinr_context_ui_help($path, $arg) {
  switch ($path) {
    case 'admin/structure/skinr/edit/%/%/%':

      // We're overriding paths in skinr_ui so make sure the proper help text
      // still appears.
      return skinr_ui_help('admin/structure/skinr/edit/%/%', $arg);
  }
}

/**
 * Callback to determine if GID already exists.
 *
 * @see skinr_context_ui_form_alter()
 * @see skinr_context_ui_group_add_form().
 */
function skinr_context_ui_group_name_exists($value, $element, $form_state) {
  return db_query_range('SELECT 1 FROM {skinr_groups} WHERE gid = :gid', 0, 1, array(
    ':gid' => $element['#field_prefix'] . $value,
  ))
    ->fetchField();
}

// -----------------------------------------------------------------------
// Form alterations.

/**
 * Implements hook_form_FORM_ID_alter().
 */
function skinr_context_ui_form_ctools_export_ui_list_form_alter(&$form, &$form_state) {

  // Removed Skinr contexts from context UI to prevent confusion.
  foreach ($form_state['object']->items as $key => $item) {
    if (isset($item->export_module) && $item->export_module == 'skinr_context') {
      unset($form_state['object']->items[$key]);
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function skinr_context_ui_form_ctools_export_ui_edit_item_form_alter(&$form, &$form_state) {
  if ($form['info']['tag']['#default_value'] == 'Skinr') {

    // Prevent changing of required elements. For some reason if we disable the
    // tag field directly it doesn't get submitted. So we make a disabled copy
    // for display.
    $form['info']['alt_tag'] = $form['info']['tag'];
    $form['info']['alt_tag']['#disabled'] = TRUE;

    // Add weight to description to ensure proper order.
    $form['info']['description']['#weight'] = 1;
    $form['info']['tag']['#type'] = 'hidden';
    unset($form['reactions']);
  }
}

/**
 * Implements hook_form_alter().
 */
function skinr_context_ui_form_skinr_ui_form_alter(&$form, $form_state, $form_id) {
  $group = skinr_context_group_load($form_state['build_info']['args'][0]['gid']);
  $form['skinr']['gid'] = array(
    '#type' => 'hidden',
    '#value' => $group->gid,
  );
  $form['skinr_group'] = array(
    '#tree' => TRUE,
    '#type' => 'container',
    // Move group settings to top.
    '#weight' => -1,
  );
  $form['skinr_group']['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Group title'),
    '#required' => TRUE,
    '#default_value' => $group->title,
    '#description' => t('Descriptive title for this skin settings group.'),
  );
  $machine_name_prefix = $group->module . ':' . $group->element . ':';
  $form['skinr_group']['gid'] = array(
    '#type' => 'machine_name',
    '#title' => t('Group name'),
    '#default_value' => strpos($group->gid, $machine_name_prefix) === 0 ? substr($group->gid, strlen($machine_name_prefix)) : $group->gid,
    // '#maxlength' => MENU_MAX_MENU_NAME_LENGTH_UI,
    '#description' => t('A unique name to identify this group. It must only contain lowercase letters, numbers, hyphens and underscores.'),
    '#field_prefix' => $machine_name_prefix,
    '#machine_name' => array(
      'exists' => 'skinr_context_ui_group_name_exists',
      'source' => array(
        'skinr_group',
        'title',
      ),
      'replace_pattern' => '[^a-z0-9-_]+',
    ),
    // A group's machine name cannot be changed.
    '#disabled' => TRUE,
  );
  $form['skinr_group']['description'] = array(
    '#type' => 'textfield',
    '#title' => t('Description'),
    '#default_value' => $group->description,
    '#description' => t('A description for this group.'),
  );

  // Context form elements.
  $context = skinr_context_group_to_context($group);

  // Condition mode
  $form['condition_mode'] = array(
    '#type' => 'checkbox',
    '#default_value' => isset($context->condition_mode) ? $context->condition_mode : FALSE,
    '#title' => t('Require all conditions'),
    '#description' => t('If checked, all conditions must be met for this context to be active. Otherwise, the first condition that is met will activate this context.'),
  );

  // Condition plugin forms
  $form['conditions'] = array(
    '#theme' => 'context_ui_plugins',
    '#title' => t('Conditions'),
    '#description' => t('Trigger the activation of this context'),
    '#tree' => TRUE,
    'selector' => array(
      '#type' => 'select',
      '#options' => array(
        0 => '<' . t('Add a condition') . '>',
      ),
      '#default_value' => 0,
    ),
    'state' => array(
      '#attributes' => array(
        'class' => array(
          'context-plugins-state',
        ),
      ),
      '#type' => 'hidden',
    ),
    'plugins' => array(
      '#tree' => TRUE,
    ),
  );
  $conditions = array_keys(context_conditions());
  sort($conditions);
  foreach ($conditions as $condition) {
    if ($plugin = context_get_plugin('condition', $condition)) {
      $form['conditions']['plugins'][$condition] = array(
        '#tree' => TRUE,
        '#plugin' => $plugin,
        '#context_enabled' => isset($context->conditions[$condition]),
        // This flag is used at the theme layer.
        'values' => $plugin
          ->condition_form($context),
        'options' => $plugin
          ->options_form($context),
      );
      $form['conditions']['selector']['#options'][$condition] = $plugin->title;
    }
  }

  // Only add submit handler once.
  if (isset($form['#submit']) && in_array('skinr_ui_form_submit', $form['#submit'])) {
    foreach ($form['#submit'] as $key => $submit_handler) {
      if ($submit_handler == 'skinr_ui_form_submit') {
        $form['#submit'][$key] = 'skinr_context_ui_form_submit';
      }
    }
  }
}

/**
 * Form submission handler for skinr_context_form_alter().
 */
function skinr_context_ui_form_submit($form, &$form_state) {
  $current_theme = skinr_current_theme(TRUE);
  $module = $form_state['values']['module'];
  $element = $form_state['values']['element'];
  $gid = $form_state['values']['gid'];

  // Save group settings.
  // Load an uncached version of the skin settings group object.
  $group = skinr_context_group_load_unchanged($gid);

  // Let's save some time in skinr_context_group_save() by setting $group->original here.
  $group->original = clone $group;

  // Update title and description.
  $group->title = $form_state['values']['skinr_group']['title'];
  $group->description = $form_state['values']['skinr_group']['description'];

  // Update context.
  if (!empty($form['conditions'])) {
    $enabled = explode(',', $form_state['values']['conditions']['state']);
    foreach ($form_state['values']['conditions']['plugins'] as $condition => $values) {
      if (in_array($condition, $enabled, TRUE) && ($plugin = context_get_plugin('condition', $condition))) {
        if (isset($values['values'])) {
          $group->conditions[$condition]['values'] = $plugin
            ->condition_form_submit($values['values']);
        }
        if (isset($values['options'])) {
          $group->conditions[$condition]['options'] = $plugin
            ->options_form_submit($values['options']);
        }
        if (context_empty($group->conditions[$condition]['values'])) {
          unset($group->conditions[$condition]);
        }
      }
      else {
        unset($group->conditions[$condition]);
      }
    }
  }
  $group->condition_mode = $form_state['values']['condition_mode'];

  // Save group.
  skinr_context_group_save($group);

  // Save skin settings.
  if (!empty($form_state['values']['skinr_settings'])) {
    foreach ($form_state['values']['skinr_settings'] as $theme_name => $theme) {

      // Process widgets.
      if (!empty($theme) && is_array($theme)) {
        foreach ($theme as $skin_name => $options) {
          if ($skin_name == '_additional' && !user_access('edit advanced skin settings')) {

            // This user doesn't have access to alter these options.
            continue;
          }

          // Ensure options is an array.
          if (!is_array($options)) {
            $options = $skin_name == '_additional' ? explode(' ', $options) : array(
              $options,
            );
          }

          // Sanitize options.
          $options = _skinr_array_strip_empty($options);

          // Find existing skin.
          $params = array(
            'theme' => $theme_name,
            'module' => $module,
            'element' => $element,
            'skin' => $skin_name,
            'gid' => $gid,
          );
          $sids = skinr_context_group_get_sids($params);
          unset($skin);
          if (!empty($sids)) {
            $sid = reset($sids);
            $skin = entity_load('skin', $sid);
          }
          if (empty($options)) {
            if (!empty($skin)) {

              // Delete this skin setting.
              $skin
                ->delete();
            }
            continue;
          }
          if (empty($skin)) {

            // It doesn't exist, so create a new skin.
            $skin = new stdClass();
            $skin->theme = $theme_name;
            $skin->module = $module;
            $skin->element = $element;
            $skin->skin = $skin_name;
            $skin->gid = $gid;
          }
          $skin->options = $options;
          $skin->status = 1;

          // Save skin.
          if (!skinr_skin_save($skin)) {
            drupal_set_message(t("Skinr settings for %skin weren't saved due to an error.", array(
              '%skin' => $skin_name,
            )), 'error');
          }
        }
      }
    }
  }
}

/**
 * Implements hook_skinr_ui_filters_alter().
 */
function skinr_context_ui_skinr_ui_filters_alter(&$filters) {

  // Group filter.
  $groups = skinr_context_group_load_multiple(FALSE);
  $options = array(
    '[any]' => t('any'),
  );
  foreach ($groups as $group) {
    $options[$group->gid] = t('@group (!gid)', array(
      '@group' => $group->title,
      '!gid' => $group->gid,
    ));
  }
  $filters['gid'] = array(
    'title' => t('group'),
    'options' => $options,
  );

  // Reorder filters.
  $skin = $filters['skin'];
  unset($filters['skin']);
  $filters['skin'] = $skin;
  $status = $filters['status'];
  unset($filters['status']);
  $filters['status'] = $status;
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function skinr_context_ui_form_skinr_ui_import_form_alter(&$form, &$form_state) {
  $form['skinr_groups'] = array(
    '#type' => 'textarea',
    '#title' => t('Skin configuration groups'),
    '#description' => t('Paste skin configuration groups here.'),
    '#rows' => 16,
    '#weight' => -1,
  );
  array_unshift($form['#validate'], 'skinr_context_ui_import_form_validate');
  array_unshift($form['#submit'], 'skinr_context_ui_import_form_submit');
}

/**
 * Form validation handler for skinr_ui_import_form().
 */
function skinr_context_ui_import_form_validate(&$form, &$form_state) {
  $error_message = t('These are not valid skin configuration groups.');
  if (empty($form_state['values']['skinr_groups'])) {

    // Error.
    form_error($form['skinr_groups'], $error_message);
    return;
  }
  $groups = '';
  ob_start();
  eval($form_state['values']['skinr_groups']);
  ob_end_clean();
  foreach ($groups as $key => $group) {
    if (!is_object($group) || !skinr_context_group_validate($groups[$key])) {
      form_error($form['skinr_groups'], $error_message);
      return;
    }
  }
  $form_state['groups'] =& $groups;
}

/**
 * Form submission handler for skinr_ui_import_form().
 */
function skinr_context_ui_import_form_submit(&$form, &$form_state) {
  $status = TRUE;
  foreach ($form_state['groups'] as $group) {
    $status = skinr_context_group_import($group, TRUE) && $status;
  }
  drupal_set_message(t('The skin configuration groups have been saved.'));
  if (!$status) {
    drupal_set_message(t('Not all skin configuration groups could be saved!'), 'error', FALSE);
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function skinr_context_ui_form_skinr_ui_export_form_alter(&$form, &$form_state) {
  if (!empty($form_state['build_info']['args'][0])) {
    $code = array();

    // Export groups for exported skins.
    $gids = array();
    foreach ($form['#skins'] as $skin) {
      if (!empty($skin->gid)) {
        $gids[$skin->gid] = $skin->gid;
      }
    }

    // Convert classes to arrays.
    $groups = array();
    if ($gids && ($groups = skinr_context_group_load_multiple($gids))) {
      foreach ($groups as $group) {
        $code[] = skinr_context_group_export($group);
      }
    }
    $code = implode("\n", $code);
    $lines = substr_count($code, "\n") + 1;
    $form['skinr_groups'] = array(
      '#type' => 'textarea',
      '#title' => t('Skin configuration groups'),
      '#default_value' => $code,
      '#rows' => min($lines, 80),
      '#weight' => 8,
    );
  }
}