Commit 2d6cfcdc authored by Steven Jones's avatar Steven Jones

Issue #1318374 by Steven Jones: Refactor code layout of classes using autoloader.

parents 7816dd14 66a1b847
<?php
/**
* A base class for the service and file handling classes that implements
* chaining of methods.
*/
class Provision_ChainedState {
protected $last_status;
protected $tokens;
/**
* Clear internal state
*/
protected function _clear_state() {
$this->last_status = NULL;
$this->tokens = NULL;
}
/**
* Return the status of the last operation.
*
* @return
* TRUE or FALSE for success or failure; NULL if there was not a previous
* operation.
*/
function status() {
return $this->last_status;
}
/**
* Log a notice into the logging system, if the last operation completed
* succesfully.
*
* @param $message
* The message to log, a string.
*/
function succeed($message) {
if ($this->last_status === TRUE) {
drush_log(dt($message, $this->tokens), 'message');
}
return $this;
}
/**
* Log a notice into the logging system, if the last operation did not
* complete succesfully.
*
* @param $message
* Log this as a error to the logging system, if the $error_codes parameter
* has been set, otherwise, log this as a warning. If the operation
* specifies an additional reason for the operation failing, it will be
* appended to this message.
*
* @param error_codes
* Generate these system level errors using the provision error bitmasks.
*/
function fail($message, $error_codes = NULL) {
if (!empty($this->tokens['@reason'])) {
$message .= ' (@reason)';
}
if ($this->last_status === FALSE) {
if (is_null($error_codes)) {
// Trigger a warning
drush_log(dt($message, $this->tokens), 'warning');
}
else {
// Trigger a sysem halting error
drush_set_error($error_codes, dt($message, $this->tokens));
}
}
return $this;
}
}
......@@ -6,7 +6,7 @@
* Provision configuration generation classes.
*/
class provisionConfig {
class Provision_Config {
/**
* Template file, a PHP file which will have access to $this and variables
* as defined in $data.
......@@ -19,9 +19,9 @@ class provisionConfig {
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 provisionConfig {
* 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 provisionConfig {
$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 provisionConfig {
$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 provisionConfig {
$class_name = get_parent_class($class_name);
}
}
}
return false;
}
......@@ -220,224 +222,3 @@ class provisionConfig {
}
}
/**
* 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 provisionConfig {
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 provisionConfig {
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';
}
}