You are here

function _features_restore in Features 7.2

Same name and namespace in other branches
  1. 6 features.module \_features_restore()
  2. 7 features.module \_features_restore()

Restore the specified modules to the default state.

Parameters

string $op: One of 'revert', 'rebuild', 'disable', 'enable'.

string[][] $items: Modules and their components to be processed according to $op. If empty, all applicable feature modules will be processed. Format: $[$module_name][] = $component E.g. $['myfeature'][] = 'field_instance'.

4 calls to _features_restore()
features_modules_disabled in ./features.module
Implements hook_modules_disabled().
features_modules_enabled in ./features.module
Implements hook_modules_enabled().
features_rebuild in ./features.module
Wrapper around _features_restore().
features_revert in ./features.module
Wrapper around _features_restore().

File

./features.module, line 1145
Main *.module file for the 'features' module.

Code

function _features_restore($op, $items = array()) {
  $lockable = FALSE;

  // Set this variable in $conf if having timeout issues during install/rebuild.
  if (variable_get('features_restore_time_limit_' . $op, FALSE) !== FALSE) {
    drupal_set_time_limit(variable_get('features_restore_time_limit_' . $op, FALSE));
  }
  module_load_include('inc', 'features', 'features.export');
  features_include();
  switch ($op) {
    case 'revert':
      $restore_states = array(
        FEATURES_OVERRIDDEN,
        FEATURES_REBUILDABLE,
        FEATURES_NEEDS_REVIEW,
      );

      /* @see \hook_pre_features_revert() - module hook. */

      /* @see \hook_features_revert() - component hook. */

      /* @see \hook_post_features_revert() - module hook. */
      $restore_hook = 'features_revert';
      $log_action = 'Revert';
      $lockable = TRUE;
      break;
    case 'rebuild':
      $restore_states = array(
        FEATURES_REBUILDABLE,
      );

      /* @see \hook_pre_features_rebuild() - module hook. */

      /* @see \hook_features_rebuild() - component hook. */

      /* @see \hook_post_features_rebuild() - module hook. */
      $restore_hook = 'features_rebuild';
      $log_action = 'Rebuild';
      $lockable = variable_get('features_lock_mode', 'all') == 'all';
      break;
    case 'disable':

      /* @see \hook_pre_features_disable_feature() - module hook. */

      /* @see \hook_features_disable_feature() - component hook. */

      /* @see \hook_post_features_disable_feature() - module hook. */
      $restore_hook = 'features_disable_feature';
      $log_action = 'Disable';
      break;
    case 'enable':

      /* @see \hook_pre_features_enable_feature() - module hook. */

      /* @see \hook_features_enable_feature() - component hook. */

      /* @see \hook_post_features_enable_feature() - module hook. */
      $restore_hook = 'features_enable_feature';
      $log_action = 'Enable';
      break;
  }
  if (empty($items)) {

    // Drush may execute a whole chain of commands that may trigger feature
    // rebuilding multiple times during a single request. Make sure we do not
    // rebuild the same cached list of modules over and over again by setting
    // $reset to TRUE.
    // Note: this may happen whenever more than one feature will be enabled
    // in chain, for example also using features_install_modules().
    $states = features_get_component_states(array(), $op == 'rebuild', defined('DRUSH_BASE_PATH'));
    foreach ($states as $module_name => $components) {
      foreach ($components as $component => $state) {
        if (in_array($state, $restore_states)) {
          $items[$module_name][] = $component;
        }
      }
    }
  }

  // Invoke global pre restore hook.
  module_invoke_all('features_pre_restore', $op, $items);
  foreach ($items as $module_name => $components) {

    // If feature is totally locked, do not execute past this stage.
    if ($lockable && features_feature_is_locked($module_name)) {
      watchdog('features', 'Tried @actioning a locked @module_name, aborted.', array(
        '@action' => $log_action,
        '@module_name' => $module_name,
      ));
      continue;
    }
    foreach ($components as $component) {

      // If feature is totally locked, do not execute past this stage.
      if ($lockable && features_feature_is_locked($module_name, $component)) {
        watchdog('features', 'Tried @actioning a locked @module_name / @component, aborted.', array(
          '@action' => $log_action,
          '@component' => $component,
          '@module_name' => $module_name,
        ));
        continue;
      }

      // Invoke pre hook.
      $pre_hook = 'pre_' . $restore_hook;
      module_invoke($module_name, $pre_hook, $component);
      if (features_hook($component, $restore_hook)) {

        // Set a semaphore to prevent other instances of the same script from
        // running concurrently.
        watchdog('features', '@actioning @module_name / @component.', array(
          '@action' => $log_action,
          '@component' => $component,
          '@module_name' => $module_name,
        ));
        features_semaphore('set', $component);
        features_invoke($component, $restore_hook, $module_name);

        // If the script completes, remove the semaphore and set the code
        // signature.
        features_semaphore('del', $component);
        features_set_signature($module_name, $component, NULL, __FUNCTION__ . '(' . $log_action . ')');
        watchdog('features', '@action completed for @module_name / @component.', array(
          '@action' => $log_action,
          '@component' => $component,
          '@module_name' => $module_name,
        ));
      }

      // Invoke post hook.
      $post_hook = 'post_' . $restore_hook;
      module_invoke($module_name, $post_hook, $component);
    }
  }

  // Invoke global post restore hook.
  module_invoke_all('features_post_restore', $op, $items);
}