provision.context.inc 3.84 KB
Newer Older
1 2 3
<?php

/**
helmo's avatar
helmo committed
4 5
 * @file
 * Provision named context base classes and the function d().
6 7 8 9 10 11 12 13 14
 */

/**
 * Store and access context objects by alias name.
 *
 * @param $name
 *   A Drush alias name, including leading @.
 * @param $_root_object
 *   Internal use only, set default object returned by d().
15 16 17
 * @param $allow_creation
 *   Defaults to TRUE. Allows creating a new context object with the specified
 *   $name.
18
 *
19
 * @return provision_Context
ergonlogic's avatar
ergonlogic committed
20
 *   provision_Context object (by reference) or NULL if it can't be loaded and
21
 *   $allow_creation == FALSE.
22
 */
23
function & d($name = NULL, $_root_object = FALSE, $allow_creation = TRUE) {
24 25 26
  static $instances = null;
  static $default_instance = '@self';

27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
  /*
   * add safety check so that we don't get caught running d() before drush is
   * fully initialized. otherwise, the proper services hooks may not be
   * properly declared and found by drush, so the object cache ($instances)
   * would be initialised with incomplete data.
   *
   * it is possible that more initialisation we need happens after
   * DRUSH_BOOTSTRAP_NONE, but this is already better than nothing.
   *
   * if something is weird with d(), it may be that it is being called too
   * early and that check is failing to detect that, so watch out, it took two
   * senior Aegir developpers three full days of headbanging on keyboards to
   * figure that stuff out.
   */
  if (drush_get_context('DRUSH_BOOTSTRAP_PHASE') == DRUSH_BOOTSTRAP_NONE) {
    $ret = drush_set_error('DRUSH_BOOTSTRAPPING', 'drush is still bootstrapping, d() should be ran only within a hook or a function');
    return $ret;
  }

46 47 48 49 50 51 52 53 54
  if (is_object($name)) {
    return $name;
  }

  if ($name == 'all') {
    return $instances;
  }

  if (is_null($name)) {
55
    $name = $default_instance;
56
  }
omega8cc's avatar
omega8cc committed
57

58 59 60
  if ($_root_object) {
    $default_instance = $name;
  }
omega8cc's avatar
omega8cc committed
61

62
  $name = provision_normalise_context_name($name);
63

64 65 66 67 68 69 70 71
  if (isset($instances[$name])) {
    return $instances[$name];
  }
  else {
    $instances[$name] = provision_context_factory($name, $allow_creation);
    if (!is_null($instances[$name])) {
      $instances[$name]->method_invoke('init');
      $instances[$name]->type_invoke('init');
72 73

      // Allow drush modules to alter the class being loaded.
helmo's avatar
helmo committed
74
      drush_command_invoke_all_ref('provision_context_alter', $instances[$name]);
75

76
    }
77
    return $instances[$name];
78 79 80 81 82 83 84
  }
}

/**
 * Simple access layer for drush_sitealias_get_record.
 *
 * Everytime sitealiases are fetched a lot of processing happens, but if the
omega8cc's avatar
omega8cc committed
85
 * file doesnt exist yet there's a whole lot of unnecesary stuff happening.
86 87 88 89 90
 *
 * We cache the result locally here.
 */
function provision_sitealias_get_record($name) {
  static $cache = array();
omega8cc's avatar
omega8cc committed
91

92
  $name = provision_normalise_context_name($name);
93 94 95 96 97 98 99 100 101

  if (!isset($cache[$name])) {
    $cache[$name] = drush_sitealias_get_record($name);
  }

  return $cache[$name];
}

/**
102 103 104 105 106 107 108 109 110 111
 * Create a new context object.
 *
 * @param $name
 *   The name of the context object to instantiate.
 * @param $allow_creation
 *   Defaults to TRUE. Allows creating a new context object with the specified
 *   $name.
 *
 * @return
 *   An instance of the specified context, or NULL if it could not be loaded.
112
 */
113
function provision_context_factory($name, $allow_creation = TRUE) {
114
  // the default type, can also be 'platform' or 'site'
115 116 117
  $type = 'server';

  $record = provision_sitealias_get_record($name);
118
  if (!$allow_creation && empty($record)) {
119
    drush_set_error('PROVISION_MISSING_CONTEXT', dt('Could not find provision alias named: @name' , array('@name' => $name)));
120 121
    return NULL;
  }
122
  $options = array_merge(drush_get_context('stdin'), drush_get_context('options'), drush_get_context('cli'));
123 124 125 126 127 128 129

  if (isset($record['context_type'])) {
    $type = $record['context_type'];
  }
  elseif (isset($options['context_type'])) {
    $type = $options['context_type'];
  }
130
  $classname = "Provision_Context_{$type}";
131 132 133

  return new $classname($name);
}