Skip to content
Snippets Groups Projects
Commit 1fa51283 authored by Ronan Dowling's avatar Ronan Dowling
Browse files

Intitial commit of rough framework

parent ba35bdd5
No related branches found
No related tags found
No related merge requests found
composer.lock
name: 'Backup and Migrate'
description: 'Backup the Drupal database and files or migrate them to another environment.'
package: Other
type: module
core: 8.x
#configure: -- pending new D8 routing format -- as per https://www.drupal.org/node/2118147 -- admin/config/system/backup_migrate
<?php
use BackupMigrate\Core\Config\Config;
require __DIR__.'/vendor/autoload.php';
/**
* Back up a source to 1 or more destinations.
*
* @param string $source_id
* @param string|array $destination_id
* @param array $config
*/
function backup_migrate_perform_backup($source_id, $destination_id, $config = []) {
try {
// Create the service
$bam = backup_migrate_get_service_object($config);
// Run the backup.
$bam->backup($source_id, $destination_id);
}
catch (Exception $e) {
die ('Caught exception: ' . $e);
}
}
/**
* Get a BackupMigrate service object.
*
* @param array $config_array
* The configuration as an array.
* @return \BackupMigrate\Core\Service\BackupMigrate
*/
function backup_migrate_get_service_object($config_array = []) {
static $bam = NULL;
// If the static cached object has not been loaded.
if ($bam === NULL) {
// Create the config object.
$conf = new \BackupMigrate\Core\Config\Config($config_array);
// Create the environment services.
$logger = new \BackupMigrate\Drupal\Environment\DrupalSetMessageLogger();
$files = new \BackupMigrate\Drupal\File\DrupalTempFileAdapter(\Drupal::service('file_system'), 'temporary://', 'bam');
// @TODO: Implement Drupal specific caching and state storage.
$cache = NULL;
$state = NULL;
$mailer = NULL;
// Bundle the services into an environment object
$env = new \BackupMigrate\Drupal\Environment\DrupalEnvironment($files, $cache, $state, $logger, $mailer);
// Create the service object.
$bam = new \BackupMigrate\Core\Service\BackupMigrate($env, $conf);
// Allow other modules to alter the object
\Drupal::moduleHandler()->alter('backup_migrate_service_object', $bam);
}
return $bam;
}
/**
* Implements hook_backup_migrate_service_object_alter().
*
* Add the core Backup and Migrate plugins to the service object.
*
* @param \BackupMigrate\Core\Service\BackupMigrate $bam
*/
function backup_migrate_backup_migrate_service_object_alter(\BackupMigrate\Core\Service\BackupMigrate &$bam) {
// Add the default database.
$info = \Drupal\Core\Database\Database::getConnectionInfo('default', 'default');
$info = $info['default'];
if ($info['driver'] == 'mysql') {
$bam->plugins()->add(
new \BackupMigrate\Core\Source\MySQLiSource(
new \BackupMigrate\Core\Config\Config($info)
), 'db');
}
// Add a download destination.
$bam->plugins()->add(new \BackupMigrate\Drupal\Destination\DrupalBrowserDownloadDestination(), 'download');
// Add a file naming filter.
$bam->plugins()->add(new \BackupMigrate\Core\Filter\FileNamer(), 'namer');
}
'access backup and migrate':
'title': 'Access Backup and Migrate'
'description': 'Access the Backup and Migrate admin section.'
restrict access: true
'perform backup':
'title': 'Perform a backup'
'description': 'Back up any of the available sources.'
restrict access: true
'access backup files':
'title': 'Access backup files'
'description': 'Access and download the previously created backup files.'
restrict access: true
'delete backup files':
'title': 'Delete backup files'
'description': 'Delete the previously created backup files.'
restrict access: true
'restore from backup':
'title': 'Restore the site'
'description': 'Restore the site''s database from a backup file.'
restrict access: true
'administer backup and migrate':
'title': 'Administer Backup and Migrate'
'description': 'Edit Backup and Migrate profiles, schedules and destinations.'
restrict access: true
backup_migrate.quick_backup:
path: '/admin/config/system/backup_migrate'
defaults:
_form: '\Drupal\backup_migrate\Form\BackupMigrateQuickBackupForm'
_title: 'Quick Backup'
requirements:
_permission: 'perform backup'
backup_migrate.advanced_backup:
path: '/admin/config/system/backup_migrate/export/advanced'
defaults:
_form: '\Drupal\backup_migrate\Form\BackupMigrateAdvancedBackupForm'
_title: 'Advanced Backup'
requirements:
_permission: 'perform backup'
# backup_migrate.restore:
# path: '/admin/config/system/backup_migrate/restore'
# defaults:
# _form: '\Drupal\backup_migrate\Form\BackupMigrateRestoreForm'
# _title: 'Restore'
# requirements:
# _permission: 'restore from backup'
{
"name": "backupmigrate/drupal",
"description": "Backup and Migrate Drupal Module",
"autoload": {
"psr-4": {
"BackupMigrate\\Drupal\\": "src"
}
},
"authors": [
{
"name": "Ronan Dowling"
}
],
"repositories": [
{
"type": "vcs",
"url": "https://github.com/backupmigrate/backup_migrate_core"
}
],
"require": {
"php": ">=5.4.0",
"backupmigrate/core": "dev-master",
"psr/log": "dev-master"
}
}
# Schema for configuration files of the Backup and Migrate module.
backup_migrate.profile.*:
type: config_entity
label: 'Backup and Migrate settings profile'
mapping:
name:
type: string
label:
type: label
label: 'Label'
label:
type: string
label: 'Filename'
append_timestamp:
type: boolean
label: 'Append Timestamp'
timestamp_format:
type: string
label: 'Timestamp Format'
backup_migrate.schedule.*:
type: config_entity
label: 'Backup and Migrate schedule'
mapping:
name:
type: string
label:
type: label
label: 'Label'
backup_migrate.source.*:
type: config_entity
label: 'Backup and Migrate backup source'
mapping:
name:
type: string
label:
type: label
label: 'Label'
backup_migrate.destination.*:
type: config_entity
label: 'Backup and Migrate backup destination'
mapping:
name:
type: string
label:
type: label
label: 'Label'
<?php
/**
* @file
* Contains BackupMigrate\Drupal\Config\DrupalConfigHelper
*/
namespace BackupMigrate\Drupal\Config;
/**
* Class DrupalConfigHelper
* @package BackupMigrate\Drupal\Config
*/
class DrupalConfigHelper {
/**
* @param array $schema
* A configuration schema from one or more Backup and Migrate plugins.
* @param array $values
*/
static public function buildFormFromSchema($schema, $values = array()) {
$form = array();
foreach ($schema['fields'] as $key => $item) {
$form_item = array();
switch ($item['type']) {
case 'text':
$form_item['#type'] = 'textfield';
break;
case 'boolean':
$form_item['#type'] = 'checkbox';
break;
}
// If there is a form item add it to the form.
if ($form_item) {
// Add the common form elements.
$form_item['#title'] = $item['title'];
$form_item['#default_value'] = isset($values) ? $values : $item['default'];
$form[$key] = $form_item;
}
}
return $form;
}
/**
* @param $schema
* @param $values
*/
static public function validateFormFromSchema($schema, $values) {
}
}
\ No newline at end of file
<?php
/**
* @file
* Contains ${NAMESPACE}\DrupalBrowserDownloadDestination
*/
namespace BackupMigrate\Drupal\Destination;
use \BackupMigrate\Core\Destination\BrowserDownloadDestination;
use BackupMigrate\Core\File\BackupFileReadableInterface;
/**
* Class DrupalBrowserDownloadDestination
* @package BackupMigrate\Drupal\Destination
*/
class DrupalBrowserDownloadDestination extends BrowserDownloadDestination {
/**
* {@inheritdoc}
*/
function saveFile(BackupFileReadableInterface $file) {
// @TODO: Replace the header/print calls with a Symfony response (if that allows streaming).
// Need to find some way to return new BinaryFileResponse($uri, 200, $headers); all the way
// out to the output of the caller.
// Probably need to provide the response as a service in the environment.
parent::saveFile($file);
// @TODO: Get rid of this ugliness:
exit();
}
}
\ No newline at end of file
<?php
/**
* @file
* Contains BackupMigrate\Drupal\Environment\DrupalEnvironment
*/
namespace BackupMigrate\Drupal\Environment;
use BackupMigrate\Core\Environment\EnvironmentBase;
/**
* Class DrupalEnvironment
* @package BackupMigrate\Drupal\Environment
*/
class DrupalEnvironment extends EnvironmentBase {}
\ No newline at end of file
<?php
/**
* @file
* Contains BackupMigrate\Drupal\Environment\DrupalLogger
*/
namespace BackupMigrate\Drupal\Environment;
use Psr\Log\AbstractLogger;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
/**
* Class DrupalLogger
* @package BackupMigrate\Drupal\Environment
*
* This logger sends messages to the browser when Backup and Migrate is run in
* interactive mode.
*/
class DrupalSetMessageLogger extends AbstractLogger {
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param array $context
*
* @return null
*/
public function log($level, $message, array $context = array()) {
// Translate the PSR logging level to a drupal message type.
switch ($level) {
case LogLevel::EMERGENCY:
case LogLevel::ALERT:
case LogLevel::CRITICAL:
case LogLevel::ERROR:
$type = 'error';
break;
case LogLevel::WARNING:
case LogLevel::NOTICE:
$type = 'warning';
break;
default:
$type = 'status';
break;
}
// @TODO: Handle translations properly.
drupal_set_message($message, $type, FALSE);
}
}
\ No newline at end of file
<?php
/**
* @file
* Contains BackupMigrate\Drupal\File\DrupalTempFileAdapter
*/
namespace BackupMigrate\Drupal\File;
use \BackupMigrate\Core\File\TempFileAdapter;
use \BackupMigrate\Core\File\TempFileAdapterInterface;
use \Drupal\Core\File\FileSystem;
/**
* Class DrupalTempFileAdapter
* @package BackupMigrate\Drupal\File
*/
class DrupalTempFileAdapter extends TempFileAdapter implements TempFileAdapterInterface
{
/**
* The Drupal file system for provisioning temp files.
*
* @var \Drupal\Core\File\FileSystem
*/
protected $filesystem;
/**
* Construct a manager
*
* @param \Drupal\Core\File\FileSystem $filesystem A file path or stream URL for the temp directory
* @param string $dir The directory to save to.
* @param string $prefix A string prefix to add to each created file.
*/
public function __construct(FileSystem $filesystem, $dir = 'temporary://', $prefix = 'bam') {
// Set the prefix and initialize the temp file tracking.
parent::__construct($dir, $prefix);
$this->filesystem = $filesystem;
}
/**
* {@inheritdoc}
*/
public function createTempFile($ext = '') {
// Add a dot to the file extension
$ext = $ext ? '.' . $ext : '';
$file = $this->filesystem->tempnam($this->dir, $this->prefix);
if (!$file) {
throw new \Exception('Could not create a temporary file to write to.');
}
$this->tempfiles[] = $file;
return $file;
}
/**
* {@inheritdoc}
*/
public function deleteTempFile($filename) {
// Only delete files that were created by this manager.
if (in_array($filename, $this->tempfiles)) {
if (file_exists($filename)) {
if (!$this->filesystem->unlink($filename)) {
throw new \Exception('Could not delete a temporary file.');
}
}
}
}
}
\ No newline at end of file
<?php
/**
* @file
* Contains \Drupal\backup_migrate\Form\BackupMigrateQuickBackupForm.
*/
namespace Drupal\backup_migrate\Form;
use BackupMigrate\Drupal\Config\DrupalConfigHelper;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Provides a form for performing a 1-click site backup.
*/
class BackupMigrateAdvancedBackupForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'backup_migrate_ui_manual_backup_advanced';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form = array();
// Theme the form if we want it inline.
// @FIXME
// $form['#theme'] = 'backup_migrate_ui_manual_quick_backup_form_inline';
$form['source'] = array(
'#type' => 'fieldset',
"#title" => t("Source"),
"#collapsible" => TRUE,
"#collapsed" => FALSE,
"#tree" => FALSE,
);
// $values = $form_state['values'];
$bam = backup_migrate_get_service_object();
$conf_schema = $bam->plugins()->call('configSchema', array(), array('operation' => 'backup'));
$form += DrupalConfigHelper::buildFormFromSchema($conf_schema, $values);
// $form['quickbackup']['source_id'] = _backup_migrate_get_source_pulldown(\Drupal::config('backup_migrate.settings')->get('backup_migrate_source_id'));
// $form['quickbackup']['destination'] = _backup_migrate_get_destination_pulldown('manual backup', \Drupal::config('backup_migrate.settings')->get('backup_migrate_destination_id'), \Drupal::config('backup_migrate.settings')->get('backup_migrate_copy_destination_id'));
$form['quickbackup']['submit'] = array(
'#type' => 'submit',
'#value' => t('Backup now'),
'#weight' => 1,
);
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
$conf_schema = $bam->plugins()->call('configSchema', array(), array('operation' => 'backup'));
DrupalConfigHelper::validateFormFromSchema($conf_schema, $form_state['values']);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = $form_state['values'];
backup_migrate_perform_backup('db', 'download', $config);
}
}
<?php
/**
* @file
* Contains \Drupal\backup_migrate\Form\BackupMigrateQuickBackupForm.
*/
namespace Drupal\backup_migrate\Form;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Provides a form for performing a 1-click site backup.
*/
class BackupMigrateQuickBackupForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'backup_migrate_ui_manual_backup_quick';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form = array();
// Theme the form if we want it inline.
// @FIXME
// $form['#theme'] = 'backup_migrate_ui_manual_quick_backup_form_inline';
$form['quickbackup'] = array(
'#type' => 'fieldset',
"#title" => t("Quick Backup"),
"#collapsible" => FALSE,
"#collapsed" => FALSE,
"#tree" => FALSE,
);
// Create the service
// $bam = backup_migrate_get_service_object($config);
// $bam->plugins()->get('namer')->confGet('filename');
// $form['quickbackup']['source_id'] = _backup_migrate_get_source_pulldown(\Drupal::config('backup_migrate.settings')->get('backup_migrate_source_id'));
// $form['quickbackup']['destination'] = _backup_migrate_get_destination_pulldown('manual backup', \Drupal::config('backup_migrate.settings')->get('backup_migrate_destination_id'), \Drupal::config('backup_migrate.settings')->get('backup_migrate_copy_destination_id'));
$form['quickbackup']['submit'] = array(
'#type' => 'submit',
'#value' => t('Backup now'),
'#weight' => 1,
);
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
backup_migrate_perform_backup('db', 'download');
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment