View source
<?php
declare (strict_types=1);
namespace Drupal\config_split;
use Drupal\config_split\Config\ConfigImporterTrait;
use Drupal\config_split\Config\StatusOverride;
use Drupal\Core\Config\ConfigImporterException;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Config\StorageComparer;
use Drupal\Core\Config\StorageCopyTrait;
use Drupal\Core\Config\StorageInterface;
class ConfigSplitCliService {
use StorageCopyTrait;
use ConfigImporterTrait;
const NO_CHANGES = 'no_changes';
const ALREADY_IMPORTING = 'already_importing';
const COMPLETE = 'complete';
private $manager;
private $activeStorage;
private $syncStorage;
protected $statusOverride;
protected $errors;
public function __construct(ConfigSplitManager $manager, StorageInterface $activeStorage, StorageInterface $syncStorage, StatusOverride $statusOverride) {
$this->manager = $manager;
$this->activeStorage = $activeStorage;
$this->syncStorage = $syncStorage;
$this->statusOverride = $statusOverride;
$this->errors = [];
}
public function ioExport(string $split, $io, callable $t, bool $confirmed = FALSE) : bool {
$config = $this
->getSplitFromArgument($split, $io, $t);
if ($config === NULL) {
return FALSE;
}
if (!$config
->get('status')) {
$io
->warning("Inactive splits can not not be exported.");
return FALSE;
}
$message = $t('Export the split config configuration?');
if ($confirmed || $io
->confirm($message)) {
$target = $this->manager
->singleExportTarget($config);
self::replaceStorageContents($this->manager
->singleExportPreview($config), $target);
$io
->success($t("Configuration successfully exported."));
}
return TRUE;
}
public function ioImport(string $split, $io, callable $t, $confirmed = FALSE) : bool {
$config = $this
->getSplitFromArgument($split, $io, $t);
if ($config === NULL) {
return FALSE;
}
$message = $t('Import the split config configuration?');
$storage = $this->manager
->singleImport($config, FALSE);
if ($confirmed || $io
->confirm($message)) {
return $this
->tryImport($storage, $io, $t);
}
return TRUE;
}
public function ioActivate(string $split, $io, callable $t, $confirmed = FALSE) : bool {
$config = $this
->getSplitFromArgument($split, $io, $t);
if ($config === NULL) {
return FALSE;
}
$message = $t('Activate the split config configuration?');
$storage = $this->manager
->singleActivate($config, TRUE);
if ($confirmed || $io
->confirm($message)) {
return $this
->tryImport($storage, $io, $t);
}
return TRUE;
}
public function ioDeactivate(string $split, $io, callable $t, $confirmed = FALSE) : bool {
$config = $this
->getSplitFromArgument($split, $io, $t);
if ($config === NULL) {
return FALSE;
}
$message = $t('Deactivate the split config configuration?');
$storage = $this->manager
->singleDeactivate($config, FALSE);
if ($confirmed || $io
->confirm($message)) {
return $this
->tryImport($storage, $io, $t);
}
return TRUE;
}
public function postExportAll() {
$this->manager
->commitAll();
}
public function statusOverride(string $name, $status, $io, callable $t) {
if ($this
->getSplitFromArgument($name, $io, $t) === NULL) {
return FALSE;
}
$map = [
NULL => 'none/default',
TRUE => 'active',
FALSE => 'inactive',
];
$settings = $this->statusOverride
->getSettingsOverride($name);
if ($settings !== NULL) {
$io
->caution($t('The status for @name is overridden in settings.php to @status', [
'@name' => $name,
'@status' => $map[$settings],
]));
}
if ($status === '') {
$state = $this->statusOverride
->getSplitOverride($name);
$io
->success($t('The status override for @name is @status', [
'@name' => $name,
'@status' => $map[$state],
]));
return TRUE;
}
switch (strtolower((string) $status)) {
case 'active':
case '1':
case 'true':
$state = TRUE;
break;
case 'inactive':
case '0':
case 'false':
$state = FALSE;
break;
case 'default':
case 'null':
case 'none':
$state = NULL;
break;
default:
throw new \InvalidArgumentException(sprintf('The status must be one of "active", "inactive", "default" or "none". %s given', $status));
}
$this->statusOverride
->setSplitOverride($name, $state);
$io
->success($t('The status override for @name was set to @status', [
'@name' => $name,
'@status' => $map[$state],
]));
return TRUE;
}
private function import(StorageInterface $storage) {
$comparer = new StorageComparer($storage, $this->activeStorage);
if (!$comparer
->createChangelist()
->hasChanges()) {
return static::NO_CHANGES;
}
$importer = $this
->getConfigImporterFromComparer($comparer);
if ($importer
->alreadyImporting()) {
return static::ALREADY_IMPORTING;
}
try {
$importer
->import();
} catch (ConfigImporterException $e) {
$this->errors = $importer
->getErrors();
throw $e;
}
return static::COMPLETE;
}
public function getErrors() {
return $this->errors;
}
private function getSplitFromArgument(string $split, $io, callable $t) : ?ImmutableConfig {
if (!$split) {
throw new \InvalidArgumentException('Split can not be empty');
}
$config = $this->manager
->getSplitConfig($split);
if ($config === NULL) {
$config = $this->manager
->getSplitConfig($split, $this->syncStorage);
if ($config === NULL) {
$io
->error($t('There is no split with name @name', [
'@name' => $split,
]));
}
}
return $config;
}
private function tryImport(StorageInterface $storage, $io, callable $t) : bool {
try {
$status = $this
->import($storage);
switch ($status) {
case ConfigSplitCliService::COMPLETE:
$io
->success($t("Configuration successfully imported."));
return TRUE;
case ConfigSplitCliService::NO_CHANGES:
$io
->text($t("There are no changes to import."));
return TRUE;
case ConfigSplitCliService::ALREADY_IMPORTING:
$io
->error($t("Another request may be synchronizing configuration already."));
return FALSE;
default:
$io
->error($t("Something unexpected happened"));
return FALSE;
}
} catch (ConfigImporterException $e) {
$io
->error($t('There have been errors importing: @errors', [
'@errors' => strip_tags(implode("\n", $this
->getErrors())),
]));
return FALSE;
}
}
}