diff --git a/src/Perspective/Repository/ElementTreeWidgetConfigRepository.php b/src/Perspective/Repository/ElementTreeWidgetConfigRepository.php index 597cd7c3c..2ae792e90 100644 --- a/src/Perspective/Repository/ElementTreeWidgetConfigRepository.php +++ b/src/Perspective/Repository/ElementTreeWidgetConfigRepository.php @@ -147,7 +147,7 @@ function ($key, $data) { public function listConfigurations(): array { $configurations = []; - $keys = array_merge(ElementTreeWidgets::values(), $this->getRepository()->fetchAllKeys()); + $keys = array_merge(ElementTreeWidgets::values(), $this->getConfigurationKeys()); foreach ($keys as $key) { $configurations[] = $this->getConfiguration($key); } @@ -179,6 +179,23 @@ public function deleteConfiguration( } } + /** + * Only the keys the configured read target can actually load: getConfiguration() reads through + * the read target, so listing a key that lives in the other location makes it fail with a not + * found error and takes the whole listing down with it. Without a read target both locations + * are read, so both sets of keys belong in the listing. + * + * @throws Exception + */ + private function getConfigurationKeys(): array + { + $repository = $this->getRepository(); + + return $repository->getReadTargets() === [] + ? $repository->fetchAllKeys() + : $repository->fetchAllKeysByReadTargets(); + } + private function getRepository(): LocationAwareConfigRepository { if (!$this->repository) { diff --git a/src/Perspective/Repository/PerspectiveConfigRepository.php b/src/Perspective/Repository/PerspectiveConfigRepository.php index 4c56fddcf..3503382ef 100644 --- a/src/Perspective/Repository/PerspectiveConfigRepository.php +++ b/src/Perspective/Repository/PerspectiveConfigRepository.php @@ -88,7 +88,7 @@ function ($key, $data) { public function listConfigurations(): array { $configurations = []; - foreach ($this->getRepository()->fetchAllKeys() as $key) { + foreach ($this->getConfigurationKeys() as $key) { $configurations[] = $this->getConfiguration($key); } @@ -119,6 +119,23 @@ public function deleteConfiguration( } } + /** + * Only the keys the configured read target can actually load: getConfiguration() reads through + * the read target, so listing a key that lives in the other location makes it fail with a not + * found error and takes the whole listing down with it. Without a read target both locations + * are read, so both sets of keys belong in the listing. + * + * @throws Exception + */ + private function getConfigurationKeys(): array + { + $repository = $this->getRepository(); + + return $repository->getReadTargets() === [] + ? $repository->fetchAllKeys() + : $repository->fetchAllKeysByReadTargets(); + } + private function getRepository(): LocationAwareConfigRepository { if (!$this->repository) { diff --git a/src/Setting/Admin/Repository/SettingRepository.php b/src/Setting/Admin/Repository/SettingRepository.php index 3dc638653..2b0be99d4 100644 --- a/src/Setting/Admin/Repository/SettingRepository.php +++ b/src/Setting/Admin/Repository/SettingRepository.php @@ -77,15 +77,20 @@ private function getRepository(): LocationAwareConfigRepository */ private function loadConfig(): array { - $data = $this->getRepository()->loadConfigByKey(Configuration::ADMIN_SETTINGS_NODE); + [$data, $dataSource] = $this->getRepository()->loadConfigByKey(Configuration::ADMIN_SETTINGS_NODE); $loadType = $this->getRepository()->getReadTargets()[0] ?? null; + // The settings store only holds the admin settings once they have been saved through the UI. + // Until then the symfony configuration is their only source, so it has to serve as the + // fallback - otherwise configured branding silently disappears as soon as the read target is + // switched to the settings store, which is the only way to keep the settings writeable in a + // production environment. The data source stays unset: the settings are still written to the + // settings store, so they remain writeable. if (!$data && $loadType === LocationAwareConfigRepository::LOCATION_SETTINGS_STORE) { - $data = $this->adminConfig; - $data['writeable'] = $this->isRepositoryWritable(); + $data = $this->adminConfig[Configuration::ADMIN_SETTINGS_NODE] ?? []; } - return $data; + return [$data, $dataSource]; } /**