Regression: Fixed enabling/disabling plugin or theme corrupting configuration

This commit is contained in:
Matias Griese
2021-02-19 22:04:04 +02:00
parent 233c7db74f
commit b7271bc424
3 changed files with 134 additions and 11 deletions

View File

@@ -3,6 +3,8 @@
1. [](#improved) 1. [](#improved)
* Flex pages admin better uses available space [#2075](https://github.com/getgrav/grav/issues/2075) * Flex pages admin better uses available space [#2075](https://github.com/getgrav/grav/issues/2075)
1. [](#bugfix)
* Regression: Fixed enabling/disabling plugin or theme corrupting configuration
# v1.10.5 # v1.10.5
## 02/18/2021 ## 02/18/2021

View File

@@ -269,7 +269,7 @@ class Admin
$name = $file->getBasename('.yaml'); $name = $file->getBasename('.yaml');
// Check that blueprint exists and is not hidden. // Check that blueprint exists and is not hidden.
$data = $admin->data('config/'. $name, null); $data = $admin->getConfigurationData('config/'. $name);
if (!is_callable([$data, 'blueprints'])) { if (!is_callable([$data, 'blueprints'])) {
continue; continue;
} }
@@ -838,12 +838,12 @@ class Admin
* Gets configuration data. * Gets configuration data.
* *
* @param string $type * @param string $type
* @param array|null $post * @param array $post
* *
* @return object * @return mixed
* @throws \RuntimeException * @throws \RuntimeException
*/ */
public function data($type, ?array $post = []) public function data($type, array $post = [])
{ {
static $data = []; static $data = [];
@@ -851,11 +851,123 @@ class Admin
return $data[$type]; return $data[$type];
} }
if (null !== $post && !$post) { if (!$post) {
$post = $this->grav['uri']->post()['data'] ?? null; $post = $this->grav['uri']->post();
if (!is_array($post)) { $post = $post['data'] ?? [];
$post = []; }
// Check to see if a data type is plugin-provided, before looking into core ones
$event = $this->grav->fireEvent('onAdminData', new Event(['type' => &$type]));
if ($event) {
if (isset($event['data_type'])) {
return $event['data_type'];
} }
if (is_string($event['type'])) {
$type = $event['type'];
}
}
/** @var UniformResourceLocator $locator */
$locator = $this->grav['locator'];
$filename = $locator->findResource("config://{$type}.yaml", true, true);
$file = CompiledYamlFile::instance($filename);
if (preg_match('|plugins/|', $type)) {
/** @var Plugins $plugins */
$plugins = $this->grav['plugins'];
$obj = $plugins->get(preg_replace('|plugins/|', '', $type));
if (!$obj) {
return [];
}
$obj->merge($post);
$obj->file($file);
$data[$type] = $obj;
} elseif (preg_match('|themes/|', $type)) {
/** @var Themes $themes */
$themes = $this->grav['themes'];
$obj = $themes->get(preg_replace('|themes/|', '', $type));
if (!$obj) {
return [];
}
$obj->merge($post);
$obj->file($file);
$data[$type] = $obj;
} elseif (preg_match('|users?/|', $type)) {
/** @var UserCollectionInterface $users */
$users = $this->grav['accounts'];
$obj = $users->load(preg_replace('|users?/|', '', $type));
$obj->update($this->cleanUserPost($post));
$data[$type] = $obj;
} elseif (preg_match('|config/|', $type)) {
$type = preg_replace('|config/|', '', $type);
$blueprints = $this->blueprints("config/{$type}");
$config = $this->grav['config'];
$obj = new Data\Data($config->get($type, []), $blueprints);
$obj->merge($post);
// FIXME: We shouldn't allow user to change configuration files in system folder!
$filename = $this->grav['locator']->findResource("config://{$type}.yaml")
?: $this->grav['locator']->findResource("config://{$type}.yaml", true, true);
$file = CompiledYamlFile::instance($filename);
$obj->file($file);
$data[$type] = $obj;
} elseif (preg_match('|media-manager/|', $type)) {
$filename = base64_decode(preg_replace('|media-manager/|', '', $type));
$file = File::instance($filename);
$pages = static::enablePages();
$obj = new \stdClass();
$obj->title = $file->basename();
$obj->path = $file->filename();
$obj->file = $file;
$obj->page = $pages->get(dirname($obj->path));
$fileInfo = pathinfo($obj->title);
$filename = str_replace(['@3x', '@2x'], '', $fileInfo['filename']);
if (isset($fileInfo['extension'])) {
$filename .= '.' . $fileInfo['extension'];
}
if ($obj->page && isset($obj->page->media()[$filename])) {
$obj->metadata = new Data\Data($obj->page->media()[$filename]->metadata());
}
$data[$type] = $obj;
} else {
throw new \RuntimeException("Data type '{$type}' doesn't exist!");
}
return $data[$type];
}
/**
* Get configuration data.
*
* Note: If you pass $post, make sure you pass all the fields in the blueprint or data gets lost!
*
* @param string $type
* @param array|null $post
*
* @return object
* @throws \RuntimeException
*/
public function getConfigurationData($type, array $post = null)
{
static $data = [];
if (isset($data[$type])) {
return $data[$type];
} }
// Check to see if a data type is plugin-provided, before looking into core ones // Check to see if a data type is plugin-provided, before looking into core ones

View File

@@ -158,7 +158,8 @@ class AdminController extends AdminBaseController
protected function taskSaveDefault() protected function taskSaveDefault()
{ {
// Handle standard data types. // Handle standard data types.
$obj = $this->prepareData((array)$this->data); $type = $this->getDataType();
$obj = $this->admin->getConfigurationData($type, $this->data);
try { try {
$obj->validate(); $obj->validate();
@@ -807,7 +808,7 @@ class AdminController extends AdminBaseController
$this->grav['themes']->get($name); $this->grav['themes']->get($name);
// Store system configuration. // Store system configuration.
$system = $this->admin->data('config/system'); $system = $this->admin->getConfigurationData('config/system');
$system->set('pages.theme', $name); $system->set('pages.theme', $name);
$system->save(); $system->save();
@@ -2686,6 +2687,14 @@ class AdminController extends AdminBaseController
return $settings + ['accept' => '*', 'limit' => 1000]; return $settings + ['accept' => '*', 'limit' => 1000];
} }
/**
* @return string
*/
protected function getDataType()
{
return trim("{$this->view}/{$this->admin->route}", '/');
}
/** /**
* Gets the configuration data for a given view & post * Gets the configuration data for a given view & post
* *
@@ -2694,7 +2703,7 @@ class AdminController extends AdminBaseController
*/ */
protected function prepareData(array $data) protected function prepareData(array $data)
{ {
$type = trim("{$this->view}/{$this->admin->route}", '/'); $type = $this->getDataType();
return $this->admin->data($type, $data); return $this->admin->data($type, $data);
} }