You are here

function features_admin_form in Features 7

Same name and namespace in other branches
  1. 6 features.admin.inc \features_admin_form()
  2. 7.2 features.admin.inc \features_admin_form()

Form constructor for the features configuration form.

1 string reference to 'features_admin_form'
features_menu in ./features.module
Implements hook_menu().

File

./features.admin.inc, line 341
@todo.

Code

function features_admin_form($form, $form_state) {

  // Load export functions to use in comparison.
  module_load_include('inc', 'features', 'features.export');

  // Clear & rebuild key caches
  features_get_info(NULL, NULL, TRUE);
  features_rebuild();
  $modules = array_filter(features_get_modules(), 'features_filter_hidden');
  $features = array_filter(features_get_features(), 'features_filter_hidden');
  $conflicts = features_get_conflicts();
  foreach ($modules as $key => $module) {
    if ($module->status && !empty($module->info['dependencies'])) {
      foreach ($module->info['dependencies'] as $dependent) {
        if (isset($features[$dependent])) {
          $features[$dependent]->dependents[$key] = $module->info['name'];
        }
      }
    }
  }
  if (empty($features)) {
    $form['no_features'] = array(
      '#markup' => t('No Features were found. Please use the !create_link link to create
      a new Feature module, or upload an existing Feature to your modules directory.', array(
        '!create_link' => l(t('Create Feature'), 'admin/structure/features/create'),
      )),
    );
    return $form;
  }
  $form = array(
    '#features' => $features,
  );

  // Generate features form. Features are sorted by dependencies, resort alpha
  ksort($features);
  foreach ($features as $name => $module) {
    $package_title = !empty($module->info['package']) ? $module->info['package'] : t('Other');
    $package = strtolower(preg_replace('/[^a-zA-Z0-9-]+/', '-', $package_title));

    // Set up package elements
    if (!isset($form[$package])) {
      $form[$package] = array(
        '#tree' => FALSE,
        '#title' => check_plain($package_title),
        '#theme' => 'features_form_package',
        '#type' => 'fieldset',
        '#group' => 'packages',
      );
      $form[$package]['links'] = $form[$package]['version'] = $form[$package]['weight'] = $form[$package]['status'] = $form[$package]['action'] = array(
        '#tree' => TRUE,
      );
    }
    $disabled = FALSE;
    $description = isset($module->info['description']) ? $module->info['description'] : '';

    // Detect unmet dependencies
    if (!empty($module->info['dependencies'])) {
      $unmet_dependencies = array();
      $dependencies = _features_export_maximize_dependencies($module->info['dependencies']);
      foreach ($dependencies as $dependency) {
        if (empty($modules[$dependency])) {
          $unmet_dependencies[] = theme('features_module_status', array(
            'status' => FEATURES_MODULE_MISSING,
            'module' => $dependency,
          ));
        }
      }
      if (!empty($unmet_dependencies)) {
        $description .= "<div class='dependencies'>" . t('Unmet dependencies: @dependencies', array(
          '@dependencies' => implode(', ', $unmet_dependencies),
        )) . "</div>";
        $disabled = TRUE;
      }
    }
    if (!empty($module->dependents)) {
      $disabled = TRUE;
      $description .= "<div class='requirements'>" . t('Required by: @dependents', array(
        '@dependents' => implode(', ', $module->dependents),
      )) . "</div>";
    }

    // Detect potential conflicts
    if (!empty($conflicts[$name])) {
      $module_conflicts = array();
      foreach (array_keys($conflicts[$name]) as $conflict) {

        // If conflicting module is disabled, indicate so in feature listing
        $status = !module_exists($conflict) ? FEATURES_MODULE_DISABLED : FEATURES_MODULE_CONFLICT;
        $module_conflicts[] = theme('features_module_status', array(
          'status' => $status,
          'module' => $conflict,
        ));

        // Only disable modules with conflicts if they are not already enabled.
        // If they are already enabled, somehow the user got themselves into a
        // bad situation and they need to be able to disable a conflicted module.
        if (module_exists($conflict) && !module_exists($name)) {
          $disabled = TRUE;
        }
      }
      $description .= "<div class='conflicts'>" . t('Conflicts with: @conflicts', array(
        '@conflicts' => implode(', ', $module_conflicts),
      )) . "</div>";
    }
    $href = "admin/structure/features/{$name}";
    $module_name = user_access('administer features') ? l($module->info['name'], $href) : $module->info['name'];
    $form[$package]['status'][$name] = array(
      '#type' => 'checkbox',
      '#title' => $module_name,
      '#description' => check_plain($description),
      '#default_value' => $module->status,
      '#disabled' => $disabled,
    );
    if (!empty($module->info['project status url'])) {
      $uri = l(truncate_utf8($module->info['project status url'], 35, TRUE, TRUE), $module->info['project status url']);
    }
    else {
      if (isset($module->info['project'], $module->info['version'], $module->info['datestamp'])) {
        $uri = l('http://drupal.org', 'http://drupal.org/project/' . $module->info['project']);
      }
      else {
        $uri = t('Unavailable');
      }
    }
    $version = !empty($module->info['version']) ? $module->info['version'] : '';
    $version = !empty($version) ? "<div class='description'>{$version}</div>" : '';
    $form[$package]['sign'][$name] = array(
      '#markup' => "{$uri} {$version}",
    );
    if (user_access('administer features')) {

      // Add status link
      if ($module->status) {
        $state = theme('features_storage_link', array(
          'storage' => FEATURES_CHECKING,
          'path' => $href,
        ));
        $state .= l(t('Check'), "admin/structure/features/{$name}/status", array(
          'attributes' => array(
            'class' => array(
              'admin-check',
            ),
          ),
        ));
        $state .= theme('features_storage_link', array(
          'storage' => FEATURES_REBUILDING,
          'path' => $href,
        ));
        $state .= theme('features_storage_link', array(
          'storage' => FEATURES_NEEDS_REVIEW,
          'path' => $href,
        ));
        $state .= theme('features_storage_link', array(
          'storage' => FEATURES_OVERRIDDEN,
          'path' => $href,
        ));
        $state .= theme('features_storage_link', array(
          'storage' => FEATURES_DEFAULT,
          'path' => $href,
        ));
      }
      elseif (!empty($conflicts[$name])) {
        $state = theme('features_storage_link', array(
          'storage' => FEATURES_CONFLICT,
          'path' => $href,
        ));
      }
      else {
        $state = theme('features_storage_link', array(
          'storage' => FEATURES_DISABLED,
          'path' => $href,
        ));
      }
      $form[$package]['state'][$name] = array(
        '#markup' => !empty($state) ? $state : '',
      );

      // Add in recreate link
      $form[$package]['actions'][$name] = array(
        '#markup' => l(t('Recreate'), "admin/structure/features/{$name}/recreate", array(
          'attributes' => array(
            'class' => array(
              'admin-update',
            ),
          ),
        )),
      );
    }
  }
  ksort($form);

  // As of 7.0 beta 2 it matters where the "vertical_tabs" element lives on the
  // the array. We add it late, but at the beginning of the array because that
  // keeps us away from trouble.
  $form = array(
    'packages' => array(
      '#type' => 'vertical_tabs',
    ),
  ) + $form;
  $form['buttons'] = array(
    '#theme' => 'features_form_buttons',
  );
  $form['buttons']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save settings'),
    '#submit' => array(
      'features_form_submit',
    ),
    '#validate' => array(
      'features_form_validate',
    ),
  );
  return $form;
}