Add usingSource method to active datasource (#5017)
This allows the `theme:sync` command to properly sync to specified targets. Fixes #4887. Replaces #4935. Credit to @bennothommo for the initial implementation.
This commit is contained in:
parent
2b22c0e49a
commit
e4571c3dd4
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use Cache;
|
||||
use Exception;
|
||||
use ApplicationException;
|
||||
use October\Rain\Halcyon\Model;
|
||||
use October\Rain\Halcyon\Processors\Processor;
|
||||
use October\Rain\Halcyon\Datasource\Datasource;
|
||||
|
|
@ -36,6 +37,11 @@ class AutoDatasource extends Datasource implements DatasourceInterface
|
|||
*/
|
||||
public $activeDatasourceKey = '';
|
||||
|
||||
/**
|
||||
* @var bool Flag to indicate that we're in "single datasource mode"
|
||||
*/
|
||||
protected $singleDatasourceMode = false;
|
||||
|
||||
/**
|
||||
* Create a new datasource instance.
|
||||
*
|
||||
|
|
@ -131,6 +137,34 @@ class AutoDatasource extends Datasource implements DatasourceInterface
|
|||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces all operations in a provided closure to run within a selected datasource.
|
||||
*
|
||||
* @param string $source
|
||||
* @param \Closure $closure
|
||||
* @return mixed
|
||||
*/
|
||||
public function usingSource(string $source, \Closure $closure)
|
||||
{
|
||||
if (!array_key_exists($source, $this->datasources)) {
|
||||
throw new ApplicationException('Invalid datasource specified.');
|
||||
}
|
||||
|
||||
// Setup the datasource for single source mode
|
||||
$previousSource = $this->activeDatasourceKey;
|
||||
$this->activeDatasourceKey = $source;
|
||||
$this->singleDatasourceMode = true;
|
||||
|
||||
// Execute the callback
|
||||
$return = $closure->call($this);
|
||||
|
||||
// Restore the datasource to auto mode
|
||||
$this->singleDatasourceMode = false;
|
||||
$this->activeDatasourceKey = $previousSource;
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Push the provided model to the specified datasource
|
||||
*
|
||||
|
|
@ -140,23 +174,19 @@ class AutoDatasource extends Datasource implements DatasourceInterface
|
|||
*/
|
||||
public function pushToSource(Model $model, string $source)
|
||||
{
|
||||
// Set the active datasource to the provided source and retrieve it
|
||||
$originalActiveKey = $this->activeDatasourceKey;
|
||||
$this->activeDatasourceKey = $source;
|
||||
$datasource = $this->getActiveDatasource();
|
||||
$this->usingSource($source, function () use ($model) {
|
||||
$datasource = $this->getActiveDatasource();
|
||||
|
||||
// Get the path parts
|
||||
$dirName = $model->getObjectTypeDirName();
|
||||
list($fileName, $extension) = $model->getFileNameParts();
|
||||
// Get the path parts
|
||||
$dirName = $model->getObjectTypeDirName();
|
||||
list($fileName, $extension) = $model->getFileNameParts();
|
||||
|
||||
// Get the file content
|
||||
$content = $datasource->getPostProcessor()->processUpdate($model->newQuery(), []);
|
||||
// Get the file content
|
||||
$content = $datasource->getPostProcessor()->processUpdate($model->newQuery(), []);
|
||||
|
||||
// Perform an update on the selected datasource (will insert if it doesn't exist)
|
||||
$this->update($dirName, $fileName, $extension, $content);
|
||||
|
||||
// Restore the original active datasource
|
||||
$this->activeDatasourceKey = $originalActiveKey;
|
||||
// Perform an update on the selected datasource (will insert if it doesn't exist)
|
||||
$this->update($dirName, $fileName, $extension, $content);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -168,20 +198,16 @@ class AutoDatasource extends Datasource implements DatasourceInterface
|
|||
*/
|
||||
public function removeFromSource(Model $model, string $source)
|
||||
{
|
||||
// Set the active datasource to the provided source and retrieve it
|
||||
$originalActiveKey = $this->activeDatasourceKey;
|
||||
$this->activeDatasourceKey = $source;
|
||||
$datasource = $this->getActiveDatasource();
|
||||
$this->usingSource($source, function () use ($model) {
|
||||
$datasource = $this->getActiveDatasource();
|
||||
|
||||
// Get the path parts
|
||||
$dirName = $model->getObjectTypeDirName();
|
||||
list($fileName, $extension) = $model->getFileNameParts();
|
||||
// Get the path parts
|
||||
$dirName = $model->getObjectTypeDirName();
|
||||
list($fileName, $extension) = $model->getFileNameParts();
|
||||
|
||||
// Perform a forced delete on the selected datasource to ensure it's removed
|
||||
$this->forceDelete($dirName, $fileName, $extension);
|
||||
|
||||
// Restore the original active datasource
|
||||
$this->activeDatasourceKey = $originalActiveKey;
|
||||
// Perform a forced delete on the selected datasource to ensure it's removed
|
||||
$this->forceDelete($dirName, $fileName, $extension);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -192,6 +218,11 @@ class AutoDatasource extends Datasource implements DatasourceInterface
|
|||
*/
|
||||
protected function getDatasourceForPath(string $path)
|
||||
{
|
||||
// Always return the active datasource when singleDatasourceMode is enabled
|
||||
if ($this->singleDatasourceMode) {
|
||||
return $this->getActiveDatasource();
|
||||
}
|
||||
|
||||
// Default to the last datasource provided
|
||||
$datasourceIndex = count($this->datasources) - 1;
|
||||
|
||||
|
|
@ -238,7 +269,12 @@ class AutoDatasource extends Datasource implements DatasourceInterface
|
|||
$pathsCache = array_reverse($this->pathCache);
|
||||
|
||||
// Get paths available in the provided dirName, allowing proper prioritization of earlier datasources
|
||||
foreach ($pathsCache as $sourcePaths) {
|
||||
foreach ($pathsCache as $datasourceKey => $sourcePaths) {
|
||||
// Only look at the active datasource if singleDatasourceMode is enabled
|
||||
if ($this->singleDatasourceMode && $datasourceKey !== $this->activeDatasourceKey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$paths = array_merge($paths, array_filter($sourcePaths, function ($path) use ($dirName, $options) {
|
||||
$basePath = $dirName . '/';
|
||||
|
||||
|
|
|
|||
|
|
@ -211,21 +211,20 @@ class ThemeSync extends Command
|
|||
*/
|
||||
protected function getModelForPath($path, $modelClass, $theme)
|
||||
{
|
||||
$originalSource = $this->datasource->activeDatasourceKey;
|
||||
$this->datasource->activeDatasourceKey = $this->source;
|
||||
return $this->datasource->usingSource($this->source, function () use ($path, $modelClass, $theme) {
|
||||
$modelObj = new $modelClass;
|
||||
|
||||
$modelObj = new $modelClass;
|
||||
$entity = $modelClass::load(
|
||||
$theme,
|
||||
str_replace($modelObj->getObjectTypeDirName() . '/', '', $path)
|
||||
);
|
||||
|
||||
$entity = $modelClass::load(
|
||||
$theme,
|
||||
str_replace($modelObj->getObjectTypeDirName() . '/', '', $path)
|
||||
);
|
||||
if (!isset($entity)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isset($entity)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->datasource->activeDatasourceKey = $originalSource;
|
||||
return $entity;
|
||||
});
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue