Commit 0cd2fd96 authored by Steven Jones's avatar Steven Jones

Move around a whole lot of code to support autoloading.

parent b6d2cd12
......@@ -19,9 +19,9 @@ class Provision_Config {
public $data = array();
/**
* A provisionContext object thie configuration relates to.
* A Provision_Context object thie configuration relates to.
*
* @var provisionContext
* @var Provision_Context
*/
public $context = null;
......@@ -64,7 +64,7 @@ class Provision_Config {
* Constructor, overriding not recommended.
*
* @param $context
* An alias name for d(), the provisionContext that this configuration
* An alias name for d(), the Provision_Context that this configuration
* is relevant to.
* @param $data
* An associative array to potentially manipulate in process() and make
......@@ -119,6 +119,7 @@ class Provision_Config {
$reflect = new reflectionObject($this);
if (isset($this->template)) {
drush_print_r($this->template);
while ($class_name) {
// Iterate through the config file's parent classes until we
// find the template file to use.
......@@ -126,6 +127,7 @@ class Provision_Config {
$base_dir = dirname($reflect->getFilename());
$file = $base_dir . '/' . $this->template;
drush_print_r($file);
if (file_exists($file) && is_readable($file)) {
drush_log("Template loaded: $file");
......@@ -134,7 +136,7 @@ class Provision_Config {
$class_name = get_parent_class($class_name);
}
}
}
return false;
}
......@@ -220,224 +222,3 @@ class Provision_Config {
}
}
/**
* Specialized class to handle the creation of drushrc.php files.
*
* This is based on the drush_save_config code, but has been abstracted
* for our purposes.
*/
class provisionConfig_drushrc extends Provision_Config {
public $template = 'provision_drushrc.tpl.php';
public $description = 'Drush configuration file';
protected $mode = 0400;
protected $context_name = 'drush';
function filename() {
return _drush_config_file($this->context_name);
}
function __construct($context, $data = array()) {
parent::__construct($context, $data);
$this->load_data();
}
function load_data() {
// we fetch the context to pass into the template based on the context name
$this->data = array_merge(drush_get_context($this->context_name), $this->data);
}
function process() {
unset($this->data['context-path']);
unset($this->data['config-file']);
$this->data['option_keys'] = array_keys($this->data);
}
}
/**
* Class to write an alias records.
*/
class provisionConfig_drushrc_alias extends provisionConfig_drushrc {
public $template = 'provision_drushrc_alias.tpl.php';
/**
* @param $name
* String '\@name' for named context.
* @param $options
* Array of string option names to save.
*/
function __construct($context, $data = array()) {
parent::__construct($context, $data);
$this->data = array(
'aliasname' => ltrim($context, '@'),
'options' => $data,
);
}
function filename() {
return drush_server_home() . '/.drush/' . $this->data['aliasname'] . '.alias.drushrc.php';
}
}
/**
* Server level config for drushrc.php files.
*/
class provisionConfig_drushrc_server extends provisionConfig_drushrc {
protected $context_name = 'user';
public $description = 'Server drush configuration';
}
/**
* Class for writing $platform/drushrc.php files.
*/
class provisionConfig_drushrc_platform extends provisionConfig_drushrc {
protected $context_name = 'drupal';
public $description = 'Platform Drush configuration file';
// platforms contain no confidential information
protected $mode = 0444;
function filename() {
return $this->root . '/drushrc.php';
}
}
/**
* Class for writing $platform/sites/$url/drushrc.php files.
*/
class provisionConfig_drushrc_site extends provisionConfig_drushrc {
protected $context_name = 'site';
public $template = 'provision_drushrc_site.tpl.php';
public $description = 'Site Drush configuration file';
function filename() {
return $this->site_path . '/drushrc.php';
}
}
/**
* Base class for data storage.
*
* This class provides a file locking mechanism for configuration
* files that may be susceptible to race conditions.
*
* The records loaded from the config and the records set in this
* instance are kept in separate arrays.
*
* When we lock the file, we load the latest stored info.
*/
class provisionConfig_data_store extends Provision_Config {
public $template = 'data_store.tpl.php';
public $key = 'record';
private $locked = FALSE;
protected $fp = null;
public $records = array();
public $loaded_records = array();
protected $mode = 0700;
function __construct($context, $data = array()) {
parent::__construct($context, $data);
$this->load_data();
}
/**
* Ensure the file pointer is closed and the lock released upon destruction.
*/
function __destruct() {
// release the file lock if we have it.
$this->close();
}
/**
* Open the file.
*/
function open() {
if (!is_resource($this->fp)) {
$this->fp = fopen($this->filename(), "w+");
}
}
/**
* Lock the file from other writes.
*
* After the file has been locked, we reload the data from the file
* so that any changes we make will not override previous changes.
*/
function lock() {
if (!$this->locked) {
$this->open();
flock($this->fp, LOCK_EX);
// Do one last load before setting our locked status.
$this->load_data();
$this->locked = TRUE;
}
}
/**
* Put the contents in the locked file.
*
* We call the lock method here to insure we have the lock.
*/
function file_put_contents($filename, $text) {
$this->lock();
fwrite($this->fp, $text);
fflush($this->fp);
}
/**
* Release the write log on the data store file.
*/
function unlock() {
if ($this->locked && is_resource($this->fp)) {
flock($this->fp, LOCK_UN);
$this->locked = FALSE;
}
}
/**
* Close the file pointer and release the lock (if applicable).
*/
function close() {
if (is_resource($this->fp)) {
fclose($this->fp);
}
}
/**
* Load the data from the data store into our loaded_records property.
*/
function load_data() {
if (!$this->locked) {
// Once we have the lock we dont need to worry about it changing
// from under us.
if (file_exists($this->filename()) && is_readable($this->filename())) {
include($this->filename());
$data_key = $this->key;
if (isset(${$data_key}) && is_array(${$data_key})) {
$this->loaded_records = ${$data_key};
}
}
}
}
/**
* Return the merged contents of the records from the data store , and the values set by us.
*
* This is basically the data that would be written to the file if we were to write it right now.
*/
function merged_records() {
return array_merge($this->loaded_records, $this->records);
}
/**
* Expose the merged records to the template file.
*/
function process() {
$this->data['records'] = array_filter(array_merge($this->loaded_records, $this->records));
}
}
<?php
/**
* Base class for data storage.
*
* This class provides a file locking mechanism for configuration
* files that may be susceptible to race conditions.
*
* The records loaded from the config and the records set in this
* instance are kept in separate arrays.
*
* When we lock the file, we load the latest stored info.
*/
class Provision_Config_Data_Store extends Provision_Config {
public $template = 'data_store.tpl.php';
public $key = 'record';
private $locked = FALSE;
protected $fp = null;
public $records = array();
public $loaded_records = array();
protected $mode = 0700;
function __construct($context, $data = array()) {
parent::__construct($context, $data);
$this->load_data();
}
/**
* Ensure the file pointer is closed and the lock released upon destruction.
*/
function __destruct() {
// release the file lock if we have it.
$this->close();
}
/**
* Open the file.
*/
function open() {
if (!is_resource($this->fp)) {
$this->fp = fopen($this->filename(), "w+");
}
}
/**
* Lock the file from other writes.
*
* After the file has been locked, we reload the data from the file
* so that any changes we make will not override previous changes.
*/
function lock() {
if (!$this->locked) {
$this->open();
flock($this->fp, LOCK_EX);
// Do one last load before setting our locked status.
$this->load_data();
$this->locked = TRUE;
}
}
/**
* Put the contents in the locked file.
*
* We call the lock method here to insure we have the lock.
*/
function file_put_contents($filename, $text) {
$this->lock();
fwrite($this->fp, $text);
fflush($this->fp);
}
/**
* Release the write log on the data store file.
*/
function unlock() {
if ($this->locked && is_resource($this->fp)) {
flock($this->fp, LOCK_UN);
$this->locked = FALSE;
}
}
/**
* Close the file pointer and release the lock (if applicable).
*/
function close() {
if (is_resource($this->fp)) {
fclose($this->fp);
}
}
/**
* Load the data from the data store into our loaded_records property.
*/
function load_data() {
if (!$this->locked) {
// Once we have the lock we dont need to worry about it changing
// from under us.
if (file_exists($this->filename()) && is_readable($this->filename())) {
include($this->filename());
$data_key = $this->key;
if (isset(${$data_key}) && is_array(${$data_key})) {
$this->loaded_records = ${$data_key};
}
}
}
}
/**
* Return the merged contents of the records from the data store , and the values set by us.
*
* This is basically the data that would be written to the file if we were to write it right now.
*/
function merged_records() {
return array_merge($this->loaded_records, $this->records);
}
/**
* Expose the merged records to the template file.
*/
function process() {
$this->data['records'] = array_filter(array_merge($this->loaded_records, $this->records));
}
}
<?php
class Provision_Config_Drupal_Alias_Store extends Provision_Config_Data_Store {
public $template = 'provision_drupal_sites.tpl.php';
public $description = 'Drupal sites.php file';
public $key = 'sites';
protected $mode = 0644;
function filename() {
return $this->root . '/sites/sites.php';
}
function maintain() {
$this->delete();
if (!$this->redirection) {
foreach ($this->aliases as $alias) {
$this->records[$alias] = $this->uri;
}
}
}
function delete() {
foreach ($this->find() as $alias) {
unset($this->records[$alias]);
unset($this->loaded_records[$alias]);
}
}
function find() {
return array_keys($this->merged_records(), $this->uri);
}
}
<?php
class Provision_Config_Drupal_Settings extends Provision_Config {
public $template = 'provision_drupal_settings.tpl.php';
public $description = 'Drupal settings.php file';
public $creds = array();
protected $mode = 0440;
function filename() {
return $this->site_path . '/settings.php';
}
function process() {
if (drush_drupal_major_version() >= 7) {
$this->data['db_type'] = ($this->data['db_type'] == 'mysqli') ? 'mysql' : $this->data['db_type'];
}
$this->version = provision_version();
$this->api_version = provision_api_version();
$this->cloaked = drush_get_option('provision_db_cloaking', $this->context->service('http')->cloaked_db_creds());
foreach (array('db_type', 'db_user', 'db_passwd', 'db_host', 'db_name', 'db_port') as $key) {
$this->creds[$key] = urldecode($this->data[$key]);
}
$this->data['extra_config'] = "# Extra configuration from modules:\n";
$this->data['extra_config'] .= join("\n", drush_command_invoke_all('provision_drupal_config', d()->uri, $this->data));
$this->group = $this->platform->server->web_group;
// Add a handy variable indicating if the site is being backed up, we can
// then react to this and change any settings we don't want backed up.
$backup_file = drush_get_option('backup_file');
$this->backup_in_progress = !empty($backup_file);
}
}
<?php
/**
* Specialized class to handle the creation of drushrc.php files.
*
* This is based on the drush_save_config code, but has been abstracted
* for our purposes.
*/
class Provision_Config_Drushrc extends Provision_Config {
public $template = 'provision_drushrc.tpl.php';
public $description = 'Drush configuration file';
protected $mode = 0400;
protected $context_name = 'drush';
function filename() {
return _drush_config_file($this->context_name);
}
function __construct($context, $data = array()) {
parent::__construct($context, $data);
$this->load_data();
}
function load_data() {
// we fetch the context to pass into the template based on the context name
$this->data = array_merge(drush_get_context($this->context_name), $this->data);
}
function process() {
unset($this->data['context-path']);
unset($this->data['config-file']);
$this->data['option_keys'] = array_keys($this->data);
}
}
<?php
/**
* Class to write an alias records.
*/
class Provision_Config_Drushrc_Alias extends Provision_Config_Drushrc {
public $template = 'provision_drushrc_alias.tpl.php';
/**
* @param $name
* String '\@name' for named context.
* @param $options
* Array of string option names to save.
*/
function __construct($context, $data = array()) {
parent::__construct($context, $data);
$this->data = array(
'aliasname' => ltrim($context, '@'),
'options' => $data,
);
}
function filename() {
return drush_server_home() . '/.drush/' . $this->data['aliasname'] . '.alias.drushrc.php';
}
}
<?php
/**
* Class for writing $platform/drushrc.php files.
*/
class Provision_Config_Drushrc_Platform extends Provision_Config_Drushrc {
protected $context_name = 'drupal';
public $description = 'Platform Drush configuration file';
// platforms contain no confidential information
protected $mode = 0444;
function filename() {
return $this->root . '/drushrc.php';
}
}
<?php
/**
* Server level config for drushrc.php files.
*/
class Provision_Config_Drushrc_Server extends Provision_Config_Drushrc {
protected $context_name = 'user';
public $description = 'Server drush configuration';
}
<?php
/**
* Class for writing $platform/sites/$url/drushrc.php files.
*/
class Provision_Config_Drushrc_Site extends Provision_Config_Drushrc {
protected $context_name = 'site';
public $template = 'provision_drushrc_site.tpl.php';
public $description = 'Site Drush configuration file';
function filename() {
return $this->site_path . '/drushrc.php';
}
}
<?php include('provision_drushrc.tpl.php'); ?>
<?php print "<?php \n"; ?>
<?php foreach ($option_keys as $key) {
print "\n\$options['$key'] = ". var_export(${$key}, TRUE) .';';
}
?>
# Aegir additions
<?php foreach (array('db_type', 'db_port', 'db_host', 'db_user', 'db_passwd', 'db_name') as $key) { ?>
......
<?php
class Provision_Config_Global_Settings extends Provision_Config {
public $template = 'global_settings.tpl.php';
public $description = 'Global settings.php file';
function filename() {
return $this->include_path . '/global.inc';
}
}
<?php
/**
* Base context class.
*
* Contains magic getter/setter functions
*/
class Provision_Context {
/**
* Name for saving aliases and referencing.
*/
public $name = null;
/**
* 'server', 'platform', or 'site'.
*/
public $type = null;
/**
* Properties that will be persisted by provision-save. Access as object
* members, $envoronment->property_name. __get() and __set handle this. In
* init(), set defaults with setProperty().
*/
protected $properties = array();
/**
* Keeps track of properites that are names of Provision_Context objects.
* Set with is_oid().
*/
protected $oid_map = array();
protected $service_subs = array();
protected $parent_key = null;
/**
* Retrieve value from $properties array if property does not exist in class
* proper. Properties that refer to Provision_Context objects will be run
* through d(), see is_oid().
*
* TODO: consider returning a reference to the value, so we can do things like:
* `$this->options['option'] = 'value'` and it will correctly set it in the
* drush context cache.
*/
function __get($name) {
if ($name == 'options') {
return array_merge(provision_sitealias_get_record($this->name), array_filter(drush_get_context('stdin')), array_filter(drush_get_context('options')), array_filter(drush_get_context('cli')));
}
if (array_key_exists($name, $this->properties)) {
if (isset($this->oid_map[$name]) && !empty($this->properties[$name])) {
return d($this->properties[$name]);
}
else {
return $this->properties[$name];
}
}
}
/**
* Specify that a property contains a named context.
*/
function is_oid($name) {
$this->oid_map[$name] = TRUE;
}
/**
* Store value in properties array if the property does not exist in class proper.
*/
function __set($name, $value) {
if (!property_exists($this, $name)) {
$this->properties[$name] = $value;
}
else {
$this->$name = $value;
}
}
/**
* Check the properties array if the property does not exist in the class proper.
*/
function __isset($name) {
return isset($this->properties[$name]) || property_exists($this, $name);
}
/**
* Remove the value from the properties array if the property does not exist
* in the class proper.
*/
function __unset($name) {
if (isset($this->properties[$name])) {
unset($this->properties[$name]);
}
elseif (property_exists($this, $name)) {
unset($this->$name);
}
}
/**
* Implement the __call magic method.
*
* This implementation is really simple. It simply return null if the
* method doesn't exist.
*
* This is used so that we can create methods for drush commands, and
* can fail safely.
*/
function __call($name, $args) {
return $this->method_invoke($name, $args);
}
/**
* Execute a method on the object and all of it's associated
* services.
*/
function method_invoke($func, $args = array(), $services = TRUE) {
provision::method_invoke($this, $func, $args);
// Services will be invoked regardless of the existence of a
// implementation in the context class.
if ($services) {
$this->services_invoke($func, $args);
}
}
/**
* Execute the method for the current object type.
*
* This function is used to avoid having to conditionally
* check the context objects type to execute the correct code.
*
* This will generate a function call like : $method_$type,
* ie: $this->init_server().
*
* Additionally it will dispatch this function call to