Completed
Push — master ( 4fe079...88ba65 )
by
unknown
22:37
created
lib/private/Config/PresetManager.php 1 patch
Indentation   +213 added lines, -213 removed lines patch added patch discarded remove patch
@@ -25,217 +25,217 @@
 block discarded – undo
25 25
  * tools to manage the Preset feature
26 26
  */
27 27
 class PresetManager {
28
-	private const PRESET_CONFIGKEY = 'config_preset';
29
-
30
-	private ?AppManager $appManager = null;
31
-	private ?Installer $installer = null;
32
-
33
-	private ?Preset $configLexiconPreset = null;
34
-
35
-	public function __construct(
36
-		private readonly IConfig $config,
37
-		private readonly ConfigManager $configManager,
38
-		private readonly LoggerInterface $logger,
39
-	) {
40
-	}
41
-
42
-	/**
43
-	 * store in config.php the new preset
44
-	 * refresh cached preset
45
-	 */
46
-	public function setLexiconPreset(Preset $preset): void {
47
-		$this->config->setSystemValue(self::PRESET_CONFIGKEY, $preset->value);
48
-		$this->configLexiconPreset = $preset;
49
-		$this->configManager->clearConfigCaches();
50
-		$this->refreshPresetApps();
51
-	}
52
-
53
-	/**
54
-	 * returns currently selected Preset
55
-	 */
56
-	public function getLexiconPreset(): Preset {
57
-		if ($this->configLexiconPreset === null) {
58
-			$this->configLexiconPreset = Preset::tryFrom($this->config->getSystemValueInt(self::PRESET_CONFIGKEY, 0)) ?? Preset::NONE;
59
-		}
60
-
61
-		return $this->configLexiconPreset;
62
-	}
63
-
64
-	/**
65
-	 * get lexicon config entries affected by Preset and its default values
66
-	 *
67
-	 * **Warning** This method MUST be considered resource-needy!
68
-	 *
69
-	 * @return array<string, list<array{config: string, defaults: array{CLUB: null|string, FAMILY: null|string, LARGE: null|string, MEDIUM: null|string, NONE: null|string, PRIVATE: null|string, SCHOOL: null|string, SHARED: null|string, SMALL: null|string, UNIVERSITY: null|string}, entry: array{definition: string, deprecated: bool, key: string, lazy: bool, note: string, type: 'ARRAY'|'BOOL'|'FLOAT'|'INT'|'MIXED'|'STRING'}, value?: mixed}>>
70
-	 */
71
-	public function retrieveLexiconPreset(?string $appId = null): array {
72
-		if ($appId === null) {
73
-			$apps = [];
74
-			foreach (['core'] + Server::get(IAppManager::class)->getEnabledApps() as $app) {
75
-				$preset = $this->retrieveLexiconPreset($app);
76
-				$apps[$app] = $preset[$app];
77
-			}
78
-			return $apps;
79
-		}
80
-
81
-		return [
82
-			$appId => array_merge(
83
-				$this->extractLexiconPresetFromConfigClass($appId, 'app', Server::get(IAppConfig::class)),
84
-				$this->extractLexiconPresetFromConfigClass($appId, 'user', Server::get(IUserConfig::class))
85
-			),
86
-		];
87
-	}
88
-
89
-	/**
90
-	 * @param string $appId
91
-	 *
92
-	 * @return list<array{config: string, defaults: array{CLUB: null|string, FAMILY: null|string, LARGE: null|string, MEDIUM: null|string, NONE: null|string, PRIVATE: null|string, SCHOOL: null|string, SHARED: null|string, SMALL: null|string, UNIVERSITY: null|string}, entry: array{definition: string, deprecated: bool, key: string, lazy: bool, note: string, type: 'ARRAY'|'BOOL'|'FLOAT'|'INT'|'MIXED'|'STRING'}, value?: mixed}>
93
-	 */
94
-	private function extractLexiconPresetFromConfigClass(
95
-		string $appId,
96
-		string $configType,
97
-		AppConfig|UserConfig $config,
98
-	): array {
99
-		$presets = [];
100
-		$lexicon = $config->getConfigDetailsFromLexicon($appId);
101
-		foreach ($lexicon['entries'] as $entry) {
102
-			$defaults = [];
103
-			foreach (Preset::cases() as $case) {
104
-				// for each case, we need to use a fresh IAppConfig with clear cache
105
-				// cloning to avoid conflict while emulating preset
106
-				$newConfig = clone $config;
107
-				if ($newConfig instanceof AppConfig) {
108
-					// needed to ignore cache and rebuild default
109
-					$newConfig->clearCache();
110
-				}
111
-				if ($newConfig instanceof UserConfig) {
112
-					// in the case of IUserConfig, clear all users' cache
113
-					$newConfig->clearCacheAll();
114
-				}
115
-
116
-				$newLexicon = $newConfig->getLexiconEntry($appId, $entry->getKey());
117
-				$defaults[$case->name] = $newLexicon?->getDefault($case);
118
-			}
119
-
120
-			// compare all value from $defaults, if more than 1 exist we have a preset
121
-			$uniqueness = array_unique($defaults);
122
-			if (count($uniqueness) < 2) {
123
-				continue;
124
-			}
125
-
126
-			$details = [
127
-				'config' => $configType,
128
-				'entry' => [
129
-					'key' => $entry->getKey(),
130
-					'type' => $entry->getValueType()->name,
131
-					'definition' => $entry->getDefinition(),
132
-					'lazy' => $entry->isLazy(),
133
-					'deprecated' => $entry->isDeprecated(),
134
-					'note' => $entry->getNote(),
135
-				],
136
-				'defaults' => $defaults
137
-			];
138
-
139
-			try {
140
-				// not interested if a users config value is already set
141
-				if ($config instanceof AppConfig) {
142
-					$details['value'] = $config->getDetails($appId, $entry->getKey())['value'];
143
-				}
144
-			} catch (AppConfigUnknownKeyException) {
145
-			}
146
-
147
-			$presets[] = $details;
148
-		}
149
-
150
-		return $presets;
151
-	}
152
-
153
-	/**
154
-	 * Enable and/or Disable a list of apps based on the currently selected Preset
155
-	 */
156
-	public function refreshPresetApps(): void {
157
-		$this->loadAppManager();
158
-
159
-		$apps = $this->getPresetApps($this->getLexiconPreset());
160
-		foreach ($apps['disabled'] ?? [] as $app) {
161
-			try {
162
-				$this->appManager->disableApp($app);
163
-			} catch (\Exception $e) {
164
-				$this->logger->warning('could not disable app', ['exception' => $e]);
165
-			}
166
-		}
167
-
168
-		foreach ($apps['enabled'] ?? [] as $app) {
169
-			$this->installApp($app);
170
-		}
171
-	}
172
-
173
-	/**
174
-	 * some parts cannot be initiated at __construct() time
175
-	 */
176
-	private function loadAppManager(): void {
177
-		if ($this->appManager === null) {
178
-			$this->appManager = Server::get(IAppManager::class);
179
-		}
180
-		if ($this->installer === null) {
181
-			$this->installer = Server::get(Installer::class);
182
-		}
183
-	}
184
-
185
-	/**
186
-	 * download, install and enable app.
187
-	 * generate warning entry in logs in case of failure.
188
-	 */
189
-	private function installApp(string $appId): void {
190
-		$this->loadAppManager();
191
-		if (!$this->installer->isDownloaded($appId)) {
192
-			try {
193
-				$this->installer->downloadApp($appId);
194
-			} catch (\Exception $e) {
195
-				$this->logger->warning('could not download app', ['appId' => $appId, 'exception' => $e]);
196
-				return;
197
-			}
198
-		}
199
-
200
-		try {
201
-			$this->installer->installApp($appId, true);
202
-		} catch (\Exception $e) {
203
-			$this->logger->warning('could not install app', ['appId' => $appId, 'exception' => $e]);
204
-			return;
205
-		}
206
-
207
-		try {
208
-			$this->appManager->enableApp($appId);
209
-		} catch (AppPathNotFoundException $e) {
210
-			$this->logger->warning('could not enable app', ['appId' => $appId, 'exception' => $e]);
211
-			return;
212
-		}
213
-	}
214
-
215
-	/**
216
-	 * return list of apps that are enabled/disabled when switching current Preset
217
-	 *
218
-	 * @return array<string, array{disabled: list<string>, enabled: list<string>}>
219
-	 */
220
-	public function retrieveLexiconPresetApps(): array {
221
-		$apps = [];
222
-		foreach (Preset::cases() as $case) {
223
-			$apps[$case->name] = $this->getPresetApps($case);
224
-		}
225
-
226
-		return $apps;
227
-	}
228
-
229
-	/**
230
-	 * get listing of enabled/disabled app from Preset
231
-	 *
232
-	 * @return array{enabled: list<string>, disabled: list<string>}
233
-	 */
234
-	private function getPresetApps(Preset $preset): array {
235
-		return match ($preset) {
236
-			Preset::CLUB, Preset::FAMILY, Preset::SCHOOL, Preset::UNIVERSITY, Preset::SMALL, Preset::MEDIUM, Preset::LARGE => ['enabled' => ['user_status', 'guests'], 'disabled' => []],
237
-			Preset::SHARED => ['enabled' => ['external'], 'disabled' => ['user_status']],
238
-			default => ['enabled' => [], 'disabled' => []],
239
-		};
240
-	}
28
+    private const PRESET_CONFIGKEY = 'config_preset';
29
+
30
+    private ?AppManager $appManager = null;
31
+    private ?Installer $installer = null;
32
+
33
+    private ?Preset $configLexiconPreset = null;
34
+
35
+    public function __construct(
36
+        private readonly IConfig $config,
37
+        private readonly ConfigManager $configManager,
38
+        private readonly LoggerInterface $logger,
39
+    ) {
40
+    }
41
+
42
+    /**
43
+     * store in config.php the new preset
44
+     * refresh cached preset
45
+     */
46
+    public function setLexiconPreset(Preset $preset): void {
47
+        $this->config->setSystemValue(self::PRESET_CONFIGKEY, $preset->value);
48
+        $this->configLexiconPreset = $preset;
49
+        $this->configManager->clearConfigCaches();
50
+        $this->refreshPresetApps();
51
+    }
52
+
53
+    /**
54
+     * returns currently selected Preset
55
+     */
56
+    public function getLexiconPreset(): Preset {
57
+        if ($this->configLexiconPreset === null) {
58
+            $this->configLexiconPreset = Preset::tryFrom($this->config->getSystemValueInt(self::PRESET_CONFIGKEY, 0)) ?? Preset::NONE;
59
+        }
60
+
61
+        return $this->configLexiconPreset;
62
+    }
63
+
64
+    /**
65
+     * get lexicon config entries affected by Preset and its default values
66
+     *
67
+     * **Warning** This method MUST be considered resource-needy!
68
+     *
69
+     * @return array<string, list<array{config: string, defaults: array{CLUB: null|string, FAMILY: null|string, LARGE: null|string, MEDIUM: null|string, NONE: null|string, PRIVATE: null|string, SCHOOL: null|string, SHARED: null|string, SMALL: null|string, UNIVERSITY: null|string}, entry: array{definition: string, deprecated: bool, key: string, lazy: bool, note: string, type: 'ARRAY'|'BOOL'|'FLOAT'|'INT'|'MIXED'|'STRING'}, value?: mixed}>>
70
+     */
71
+    public function retrieveLexiconPreset(?string $appId = null): array {
72
+        if ($appId === null) {
73
+            $apps = [];
74
+            foreach (['core'] + Server::get(IAppManager::class)->getEnabledApps() as $app) {
75
+                $preset = $this->retrieveLexiconPreset($app);
76
+                $apps[$app] = $preset[$app];
77
+            }
78
+            return $apps;
79
+        }
80
+
81
+        return [
82
+            $appId => array_merge(
83
+                $this->extractLexiconPresetFromConfigClass($appId, 'app', Server::get(IAppConfig::class)),
84
+                $this->extractLexiconPresetFromConfigClass($appId, 'user', Server::get(IUserConfig::class))
85
+            ),
86
+        ];
87
+    }
88
+
89
+    /**
90
+     * @param string $appId
91
+     *
92
+     * @return list<array{config: string, defaults: array{CLUB: null|string, FAMILY: null|string, LARGE: null|string, MEDIUM: null|string, NONE: null|string, PRIVATE: null|string, SCHOOL: null|string, SHARED: null|string, SMALL: null|string, UNIVERSITY: null|string}, entry: array{definition: string, deprecated: bool, key: string, lazy: bool, note: string, type: 'ARRAY'|'BOOL'|'FLOAT'|'INT'|'MIXED'|'STRING'}, value?: mixed}>
93
+     */
94
+    private function extractLexiconPresetFromConfigClass(
95
+        string $appId,
96
+        string $configType,
97
+        AppConfig|UserConfig $config,
98
+    ): array {
99
+        $presets = [];
100
+        $lexicon = $config->getConfigDetailsFromLexicon($appId);
101
+        foreach ($lexicon['entries'] as $entry) {
102
+            $defaults = [];
103
+            foreach (Preset::cases() as $case) {
104
+                // for each case, we need to use a fresh IAppConfig with clear cache
105
+                // cloning to avoid conflict while emulating preset
106
+                $newConfig = clone $config;
107
+                if ($newConfig instanceof AppConfig) {
108
+                    // needed to ignore cache and rebuild default
109
+                    $newConfig->clearCache();
110
+                }
111
+                if ($newConfig instanceof UserConfig) {
112
+                    // in the case of IUserConfig, clear all users' cache
113
+                    $newConfig->clearCacheAll();
114
+                }
115
+
116
+                $newLexicon = $newConfig->getLexiconEntry($appId, $entry->getKey());
117
+                $defaults[$case->name] = $newLexicon?->getDefault($case);
118
+            }
119
+
120
+            // compare all value from $defaults, if more than 1 exist we have a preset
121
+            $uniqueness = array_unique($defaults);
122
+            if (count($uniqueness) < 2) {
123
+                continue;
124
+            }
125
+
126
+            $details = [
127
+                'config' => $configType,
128
+                'entry' => [
129
+                    'key' => $entry->getKey(),
130
+                    'type' => $entry->getValueType()->name,
131
+                    'definition' => $entry->getDefinition(),
132
+                    'lazy' => $entry->isLazy(),
133
+                    'deprecated' => $entry->isDeprecated(),
134
+                    'note' => $entry->getNote(),
135
+                ],
136
+                'defaults' => $defaults
137
+            ];
138
+
139
+            try {
140
+                // not interested if a users config value is already set
141
+                if ($config instanceof AppConfig) {
142
+                    $details['value'] = $config->getDetails($appId, $entry->getKey())['value'];
143
+                }
144
+            } catch (AppConfigUnknownKeyException) {
145
+            }
146
+
147
+            $presets[] = $details;
148
+        }
149
+
150
+        return $presets;
151
+    }
152
+
153
+    /**
154
+     * Enable and/or Disable a list of apps based on the currently selected Preset
155
+     */
156
+    public function refreshPresetApps(): void {
157
+        $this->loadAppManager();
158
+
159
+        $apps = $this->getPresetApps($this->getLexiconPreset());
160
+        foreach ($apps['disabled'] ?? [] as $app) {
161
+            try {
162
+                $this->appManager->disableApp($app);
163
+            } catch (\Exception $e) {
164
+                $this->logger->warning('could not disable app', ['exception' => $e]);
165
+            }
166
+        }
167
+
168
+        foreach ($apps['enabled'] ?? [] as $app) {
169
+            $this->installApp($app);
170
+        }
171
+    }
172
+
173
+    /**
174
+     * some parts cannot be initiated at __construct() time
175
+     */
176
+    private function loadAppManager(): void {
177
+        if ($this->appManager === null) {
178
+            $this->appManager = Server::get(IAppManager::class);
179
+        }
180
+        if ($this->installer === null) {
181
+            $this->installer = Server::get(Installer::class);
182
+        }
183
+    }
184
+
185
+    /**
186
+     * download, install and enable app.
187
+     * generate warning entry in logs in case of failure.
188
+     */
189
+    private function installApp(string $appId): void {
190
+        $this->loadAppManager();
191
+        if (!$this->installer->isDownloaded($appId)) {
192
+            try {
193
+                $this->installer->downloadApp($appId);
194
+            } catch (\Exception $e) {
195
+                $this->logger->warning('could not download app', ['appId' => $appId, 'exception' => $e]);
196
+                return;
197
+            }
198
+        }
199
+
200
+        try {
201
+            $this->installer->installApp($appId, true);
202
+        } catch (\Exception $e) {
203
+            $this->logger->warning('could not install app', ['appId' => $appId, 'exception' => $e]);
204
+            return;
205
+        }
206
+
207
+        try {
208
+            $this->appManager->enableApp($appId);
209
+        } catch (AppPathNotFoundException $e) {
210
+            $this->logger->warning('could not enable app', ['appId' => $appId, 'exception' => $e]);
211
+            return;
212
+        }
213
+    }
214
+
215
+    /**
216
+     * return list of apps that are enabled/disabled when switching current Preset
217
+     *
218
+     * @return array<string, array{disabled: list<string>, enabled: list<string>}>
219
+     */
220
+    public function retrieveLexiconPresetApps(): array {
221
+        $apps = [];
222
+        foreach (Preset::cases() as $case) {
223
+            $apps[$case->name] = $this->getPresetApps($case);
224
+        }
225
+
226
+        return $apps;
227
+    }
228
+
229
+    /**
230
+     * get listing of enabled/disabled app from Preset
231
+     *
232
+     * @return array{enabled: list<string>, disabled: list<string>}
233
+     */
234
+    private function getPresetApps(Preset $preset): array {
235
+        return match ($preset) {
236
+            Preset::CLUB, Preset::FAMILY, Preset::SCHOOL, Preset::UNIVERSITY, Preset::SMALL, Preset::MEDIUM, Preset::LARGE => ['enabled' => ['user_status', 'guests'], 'disabled' => []],
237
+            Preset::SHARED => ['enabled' => ['external'], 'disabled' => ['user_status']],
238
+            default => ['enabled' => [], 'disabled' => []],
239
+        };
240
+    }
241 241
 }
Please login to merge, or discard this patch.