You are here

environment.module in Environment 6

Same filename and directory in other branches
  1. 8 environment.module
  2. 7 environment.module

File

environment.module
View source
<?php

/**
 * @file
 * Module for handling changes in server environments
 */
if (module_exists('context')) {
  include_once 'plugins/environment.context.inc';
}
if (module_exists('token')) {
  include_once 'plugins/environment.token.inc';
}

/**
 * Implementation of hook_init().
 */
function environment_init() {

  // Trigger environment context condition.
  if (module_exists('context') && function_exists('context_get_plugin') && ($plugin = context_get_plugin('condition', 'environment'))) {
    $plugin
      ->execute((array) variable_get('environment', array()));
  }
}

/**
 * Implementation of hook_menu().
 */
function environment_menu() {
  $items = array();
  $items['admin/settings/environment'] = array(
    'title' => 'Environment',
    'description' => 'Settings for Environment.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'environment_admin_settings',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'environment.admin.inc',
  );
  $items['admin/settings/environment/switch/%environment'] = array(
    'title' => 'Environment Switch',
    'description' => 'Switch the current environment.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'environment_switch_confirm',
      4,
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'environment.admin.inc',
  );
  return $items;
}

/**
 * Implementation of hook_environment().
 */
function environment_environment() {
  return array(
    'production' => array(
      'label' => t('Production'),
      'allowed' => array(
        'default' => TRUE,
      ),
    ),
    'development' => array(
      'label' => t('Development'),
      'allowed' => array(
        'default' => FALSE,
      ),
    ),
  );
}

/**
 * Implementation of hook_environment_workflow().
 */
function environment_environment_workflow() {
  return array(
    'default' => array(
      'label' => t('Default'),
    ),
  );
}

/**
 * Check if something is allowed in the current environment.
 *
 * @param $name
 *   Name of the thing to check if allowed, eg. function.
 * @param $category
 *   Optional; category of the thing to check for, eg. name of module. Defaults to 'other'.
 * @param $default
 *   Optional; what the default should be if no environment value is found. Defaults to FALSE.
 * @param $workflow
 *   Optional; specify the workflow state to check for allowance.
 *
 * @return
 *   TRUE or FALSE for whether the thing is allowed.
 */
function environment_allowed($name, $category = 'other', $default = FALSE, $workflow = 'default') {
  $env = environment_current($workflow, NULL, TRUE);
  if (!empty($env)) {
    if (!empty($env[$category])) {
      if (isset($env[$category][$name])) {
        $result = $env[$category][$name];
      }
      elseif (isset($env[$category]['default'])) {
        $result = $env[$category]['default'];
      }
    }
    if (!isset($result) && isset($env['default'])) {
      $result = $env['default'];
    }
  }
  if (!isset($result)) {
    $result = $default;
  }
  return $result;
}

/**
 * Switches between two environments.
 *
 * @param String $target_env
 *   Name of the environment to change to.
 * @param Boolean $force
 *   (optional) Whether to trigger a change even if the environment is the currently set one. Defaults to FALSE.
 *
 * @return
 *   Return messages telling what has happened.
 */
function environment_switch($target_env, $force = FALSE) {
  $result = FALSE;
  $messages = array();
  $target_state = environment_load($target_env);
  $workflow = $target_state['workflow'];
  $current_env = environment_current($workflow);
  $override = variable_get('environment_override', '');
  if ($current_env == $target_env) {
    drupal_set_message(t("The current environment is already set to '!environment'.", array(
      '!environment' => $target_env,
    )), 'error');

    // Since this option is only available in drush, only display it to drush users.
    if (function_exists('drush_print')) {
      drush_print("To force the environment switch to run anyway, use the '--force' flag.");
    }
  }
  if (!$force && !empty($override)) {
    drupal_set_message(t("The current environment is overriden with '!override'.", array(
      '!override' => $override,
    )), 'error');

    // Since this option is only available in drush, only display it to drush users.
    if (function_exists('drush_print')) {
      drush_print("To force the environment switch to run anyway, use the '--force' flag.");
    }
  }
  elseif ($current_env != $target_env || $force) {
    if (empty($target_state)) {
      drupal_set_message(t('Environment !environment does not exist.', array(
        '!environment' => $target_env,
      )), 'warning');
    }
    else {
      environment_set($target_env);
      module_invoke_all('environment_switch', $target_env, $current_env, $workflow);
      drupal_flush_all_caches();
      drupal_set_message('Cleared cache.');
      $result = TRUE;
    }
  }
  return $result;
}

/**
 * Gets the current environment.
 *
 * @param $workflow
 *  (default: default) Specify an environment workflow to check. If NULL, will
 *  return the current environment state for each workflow. Default workflow
 *  will check environment states not assigned an explicit workflow, this
 *  maintains backwards compatibility.
 * @param $default
 *  Optional; defaults to NULL. Specify the default value if the current
 *  environment cannot be identified.
 * @param $load
 *  (default: FALSE) If TRUE, loads the full environment definition.
 */
function environment_current($workflow = 'default', $default = NULL, $load = FALSE) {
  $current = variable_get('environment', array());
  if (!is_array($current)) {
    $current = array(
      'default' => $current,
    );
  }
  if (is_null($workflow)) {
    $current = empty($current) ? $default : $current;
    return $load ? environment_load($current) : $current;
  }
  elseif (isset($current[$workflow])) {
    $current[$workflow] = empty($current[$workflow]) ? $default : $current[$workflow];
    return $load ? environment_load($current[$workflow]) : $current[$workflow];
  }
  return $default;
}

/**
 * Save the new environment to it's assigned workflow.
 *
 * @param $new_env
 *  Machine name of the new system environment. If environment has a workflow
 */
function environment_set($new_env) {
  $environment = variable_get('environment', array());
  $new_state = environment_load($new_env);

  // Maintain backwards compatibility with pre-workflow systems.
  if (!is_array($environment)) {
    $environment = array(
      'default' => $environment,
    );
  }
  $environment[$new_state['workflow']] = $new_state['name'];
  variable_set('environment', $environment);
}

/**
 * Fetches all available environments.
 *
 * @param $env
 *   (optional) Name of the environment. If NULL, will return all environments.
 *   If an array, will return all environments specified in the array.
 * @param $reset
 *   (default: FALSE) Reset the static cache and collect new data.
 *
 * @return
 *   Return all environments or the specified environment.
 */
function environment_load($env = NULL, $reset = FALSE) {
  static $environments;
  if (!isset($environments) || $reset) {
    $environments = module_invoke_all('environment');
    $environments = array_merge($environments, variable_get('environment_definitions', array()));
    foreach ($environments as $name => $environment) {
      $environments[$name]['name'] = $name;
      if (!isset($environments[$name]['workflow'])) {
        $environments[$name]['workflow'] = 'default';
      }
    }
    drupal_alter('environment', $environments);
  }
  if (empty($env)) {
    return $environments;
  }
  elseif (is_array($env)) {
    return array_intersect_key($environments, array_flip($env));
  }
  else {
    return isset($environments[$env]) ? $environments[$env] : FALSE;
  }
}

/**
 * Get the current assortment of Workflows.
 *
 * @param $name
 *  Name of the workflow to retrieve information on.
 *  Use 'default' to specify default or NULL workflow.
 * @param $reset
 *  Optional; reset the static cache.
 *
 * @return Array
 */
function environment_workflow_load($name = NULL, $reset = FALSE) {
  static $workflows;
  if (empty($workflows) || $reset) {
    $workflows = module_invoke_all('environment_workflow');
    drupal_alter('environment_workflow', $workflows);
  }
  return isset($name) ? $workflows[$name] : $workflows;
}

/**
 * Provides environment form options.
 *
 * @param $workflow
 *  Optional; specify the workflow for specific options. Defaults to states
 *  that are not part of an explicit workflow.
 * @param $prefix
 *  Optional; prefix the environment label with the specified string. Defaults
 *  to no prefix.
 * @param $reset
 *  Optional; reset the static cache.
 *
 * @return
 *  Array of form options in the style of environment => label
 */
function _environment_state_options($workflow = 'default', $prefix = '', $reset = FALSE) {
  static $options;
  if (empty($options) || $reset) {
    $environments = environment_load();
    foreach ($environments as $name => $state) {
      $options[$state['workflow']][$name] = $prefix . $state['label'];
    }
  }
  return empty($options[$workflow]) ? array() : $options[$workflow];
}

/**
 * Build an options widget with all workflows.
 *
 * Options do not need namespacing because environment machine name is unique.
 * If the same environment needs to come up in multiple places, that should be
 * handled by duplicating the definition and changing the machine name.
 *
 * @param $reset
 *  Optional; reset the static cache.
 *
 * @see hook_environment
 */
function _environment_state_options_all($reset = FALSE) {
  $options = array();
  $workflows = environment_workflow_load();
  foreach ($workflows as $name => $workflow) {
    $options[$name] = $workflow['label'];
    $w_opts = _environment_state_options($name, TRUE, '-- ', $reset);
    $options = array_merge($options, $w_opts);
  }
  return $options;
}

Functions

Namesort descending Description
environment_allowed Check if something is allowed in the current environment.
environment_current Gets the current environment.
environment_environment Implementation of hook_environment().
environment_environment_workflow Implementation of hook_environment_workflow().
environment_init Implementation of hook_init().
environment_load Fetches all available environments.
environment_menu Implementation of hook_menu().
environment_set Save the new environment to it's assigned workflow.
environment_switch Switches between two environments.
environment_workflow_load Get the current assortment of Workflows.
_environment_state_options Provides environment form options.
_environment_state_options_all Build an options widget with all workflows.