<?php

/*
 * @file
 * Drupal Module: Hidden Features
 * Gives site administrators possibility to hide features from the manage tab.
 * In order to also speed up the page load of the manage tab, one wants to hide
 * all features one is not currently working on.
 *
 * @author: TimBrandin <http://drupal.org/user/738462>
 */

/**
 * Implements hook_menu().
 */
function hidden_features_menu() {
  $items = array();

  // Create a new tab in the feature administration.
  $items['admin/structure/features/hidden'] = array(
    'title' => 'Hidden',
    'description' => 'Hide features.',
    'type' => MENU_LOCAL_TASK,
    'page callback' => 'drupal_get_form',
    'page arguments' => array('hidden_features_admin_form'),
    'access arguments' => array('administer features'),
  );

  return $items;
}

/**
 * Form to manage hidden_features configuration.
 */
function hidden_features_admin_form($form, $form_state) {
  // Load admin form for features.
  module_load_include('inc', 'features', 'features.admin');
  $form_state += form_state_defaults();
  $form = drupal_retrieve_form('features_admin_form', $form_state);

  // Load stored settings from variable.
  $hidden_features = variable_get('hidden_features', array());
  $features = array_filter(features_get_features(), 'features_filter_hidden');

  // Repurposes the checkboxes to manage hidden_features functionality.
  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 the checkbox default value of the current feature.
    $form[$package]['status'][$name]['#default_value'] = in_array($module->name, $hidden_features);
    unset($form[$package]['status'][$name]['#disabled']);
  }

  // Repurposes handlers to handle hidden hidden_features functionality.
  $form['buttons']['submit'] = array(
    '#submit' => array('hidden_features_form_submit'),
    '#validate' => array(),
  );

  return $form;
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Hides the features and empty packages.
 */
function hidden_features_form_features_admin_form_alter(&$form, &$form_state) {
  $packages = array();
  $hidden_features = variable_get('hidden_features', array());

  foreach ($form['#features'] as $key => &$feature) {
    $package = preg_replace('/\s/', '-', strtolower($feature->info['package'])); 
    if (!isset($packages[$package])) {
      $packages[$package] = array();
    }

    // Remove hidden features from the manage features form.
    if (in_array($key, $hidden_features)) {
      unset($form[$package]['status'][$key]);
      unset($form[$package]['sign'][$key]);
      unset($form[$package]['state'][$key]);
      unset($form[$package]['actions'][$key]);
    }
    else {
      $packages[$package][$key] = $key;
    }
  }
  // Hide empty packages.
  foreach ($packages as $package_key => $package) {
    if (count($package) == 0) {
      $form[$package_key]['#access'] = FALSE;
    }
  }
}

/**
 * Submit handler for hidden features that saves configuration.
 */
function hidden_features_form_submit($form, &$form_submit) {
  variable_set('hidden_features', array_keys(array_filter($form_submit['values']['status'])));
}