adasd
This commit is contained in:
235
src/App/AdminAppsService.php
Normal file
235
src/App/AdminAppsService.php
Normal file
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App;
|
||||
|
||||
use Desktop\AppRegistry;
|
||||
use Desktop\WidgetRegistry;
|
||||
use ModulesCore\ModuleRegistry;
|
||||
use SystemAddons\GiteaDeployStatus\GiteaDeployStatusService;
|
||||
|
||||
final class AdminAppsService
|
||||
{
|
||||
public function __construct(
|
||||
private readonly string $projectRoot,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function bootstrap(bool $isAdmin): array
|
||||
{
|
||||
require_once AppPaths::systemAddonPath($this->projectRoot, 'gitea-deploy-status') . '/GiteaDeployStatusService.php';
|
||||
|
||||
$moduleRegistry = new ModuleRegistry(AppPaths::customAppsRoot($this->projectRoot));
|
||||
$appRegistry = new AppRegistry($this->projectRoot . '/config/apps.php', $moduleRegistry->desktopApps());
|
||||
$widgetRegistry = new WidgetRegistry($this->projectRoot . '/config/widgets.php', $moduleRegistry->widgets());
|
||||
|
||||
$apps = $this->normalizeApps($appRegistry->all());
|
||||
$widgets = $this->normalizeWidgets($widgetRegistry->all());
|
||||
$giteaConfig = ConfigLoader::load($this->projectRoot, 'gitea');
|
||||
$giteaService = new GiteaDeployStatusService($giteaConfig);
|
||||
$currentEnvironment = ConfigLoader::currentEnvironment();
|
||||
|
||||
return [
|
||||
'meta' => [
|
||||
'environment' => $currentEnvironment,
|
||||
'gitea_config_path' => $this->environmentConfigPath('gitea', $currentEnvironment),
|
||||
],
|
||||
'stats' => [
|
||||
'apps_total' => count($apps),
|
||||
'installable_apps' => count(array_filter($apps, static fn (array $app): bool => !empty($app['installable']))),
|
||||
'system_tools' => count(array_filter($apps, static fn (array $app): bool => ($app['app_scope'] ?? '') === 'system_tool')),
|
||||
'widgets_total' => count($widgets),
|
||||
'admin_only_apps' => count(array_filter($apps, static fn (array $app): bool => !empty($app['admin_only']))),
|
||||
],
|
||||
'apps' => $apps,
|
||||
'widgets' => $widgets,
|
||||
'gitea' => [
|
||||
'config' => [
|
||||
'base_url' => (string) ($giteaConfig['base_url'] ?? ''),
|
||||
'token' => (string) ($giteaConfig['token'] ?? ''),
|
||||
'owner' => (string) ($giteaConfig['owner'] ?? ''),
|
||||
'repositories' => array_values(array_map('strval', (array) ($giteaConfig['repositories'] ?? []))),
|
||||
'poll_idle_seconds' => max(1, (int) ($giteaConfig['poll_idle_seconds'] ?? 5)),
|
||||
'poll_running_seconds' => max(1, (int) ($giteaConfig['poll_running_seconds'] ?? 3)),
|
||||
'visibility' => (string) ($giteaConfig['visibility'] ?? 'admins'),
|
||||
],
|
||||
'diagnostics' => $giteaService->diagnostics(),
|
||||
'tray_visible_for_current_user' => $giteaService->shouldShowInTray($isAdmin),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $input
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function saveGiteaConfig(array $input): array
|
||||
{
|
||||
$environment = ConfigLoader::currentEnvironment();
|
||||
$config = [
|
||||
'base_url' => $this->sanitizeBaseUrl((string) ($input['base_url'] ?? '')),
|
||||
'token' => trim((string) ($input['token'] ?? '')),
|
||||
'owner' => trim((string) ($input['owner'] ?? '')),
|
||||
'repositories' => $this->sanitizeRepositories((string) ($input['repositories'] ?? '')),
|
||||
'poll_idle_seconds' => $this->sanitizePositiveInt($input['poll_idle_seconds'] ?? 5, 5),
|
||||
'poll_running_seconds' => $this->sanitizePositiveInt($input['poll_running_seconds'] ?? 3, 3),
|
||||
'visibility' => $this->sanitizeVisibility((string) ($input['visibility'] ?? 'admins')),
|
||||
];
|
||||
|
||||
$this->writeEnvironmentConfig('gitea', $environment, $config);
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<string, mixed>> $apps
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private function normalizeApps(array $apps): array
|
||||
{
|
||||
$normalized = array_map(static function (array $app): array {
|
||||
$requiredGroups = array_values(array_map('strval', (array) ($app['required_groups'] ?? [])));
|
||||
|
||||
return [
|
||||
'app_id' => (string) ($app['app_id'] ?? ''),
|
||||
'title' => (string) ($app['title'] ?? ''),
|
||||
'summary' => trim((string) ($app['summary'] ?? '')),
|
||||
'entry_route' => (string) ($app['entry_route'] ?? ''),
|
||||
'app_scope' => (string) ($app['app_scope'] ?? 'module'),
|
||||
'module_name' => (string) ($app['module_name'] ?? ''),
|
||||
'installable' => !array_key_exists('installable', $app) || (bool) $app['installable'],
|
||||
'show_on_desktop' => !empty($app['show_on_desktop']),
|
||||
'supports_widget' => !empty($app['supports_widget']),
|
||||
'supports_tray' => !empty($app['supports_tray']),
|
||||
'enabled_by_default' => !empty($app['enabled_by_default']),
|
||||
'required_groups' => $requiredGroups,
|
||||
'admin_only' => in_array('administrators', array_map(
|
||||
static fn (string $group): string => strtolower(trim($group, '/')),
|
||||
$requiredGroups
|
||||
), true),
|
||||
'source' => isset($app['module_id']) ? 'custom_app' : 'system',
|
||||
];
|
||||
}, $apps);
|
||||
|
||||
usort($normalized, static fn (array $left, array $right): int => [$left['title'], $left['app_id']] <=> [$right['title'], $right['app_id']]);
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<string, mixed>> $widgets
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private function normalizeWidgets(array $widgets): array
|
||||
{
|
||||
$normalized = array_map(static function (array $widget): array {
|
||||
return [
|
||||
'widget_id' => (string) ($widget['widget_id'] ?? ''),
|
||||
'title' => (string) ($widget['title'] ?? ''),
|
||||
'summary' => trim((string) ($widget['summary'] ?? '')),
|
||||
'zone' => (string) ($widget['zone'] ?? 'sidebar'),
|
||||
'default_enabled' => !empty($widget['default_enabled']),
|
||||
'source_app_id' => (string) ($widget['source_app_id'] ?? ''),
|
||||
'source_module_id' => (string) ($widget['source_module_id'] ?? ''),
|
||||
'launch_app_id' => (string) ($widget['launch_app_id'] ?? ''),
|
||||
'status_api' => isset($widget['status_api']) ? (string) $widget['status_api'] : '',
|
||||
];
|
||||
}, $widgets);
|
||||
|
||||
usort($normalized, static fn (array $left, array $right): int => [$left['title'], $left['widget_id']] <=> [$right['title'], $right['widget_id']]);
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
private function sanitizeBaseUrl(string $value): string
|
||||
{
|
||||
return rtrim(trim($value), '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, string>
|
||||
*/
|
||||
private function sanitizeRepositories(string $value): array
|
||||
{
|
||||
$entries = preg_split('/[\r\n,;]+/', $value) ?: [];
|
||||
$result = [];
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
$normalized = trim($entry);
|
||||
if ($normalized === '' || !preg_match('/^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/', $normalized)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[$normalized] = $normalized;
|
||||
}
|
||||
|
||||
return array_values($result);
|
||||
}
|
||||
|
||||
private function sanitizePositiveInt(mixed $value, int $fallback): int
|
||||
{
|
||||
$normalized = (int) $value;
|
||||
|
||||
return $normalized > 0 ? $normalized : $fallback;
|
||||
}
|
||||
|
||||
private function sanitizeVisibility(string $value): string
|
||||
{
|
||||
$normalized = strtolower(trim($value));
|
||||
|
||||
return in_array($normalized, ['all', 'admins', 'disabled'], true) ? $normalized : 'admins';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $config
|
||||
*/
|
||||
private function writeEnvironmentConfig(string $name, string $environment, array $config): void
|
||||
{
|
||||
$directory = $this->projectRoot . '/config/' . $environment;
|
||||
if (!is_dir($directory) && !mkdir($directory, 0775, true) && !is_dir($directory)) {
|
||||
throw new \RuntimeException('Konfigurationsverzeichnis konnte nicht angelegt werden.');
|
||||
}
|
||||
|
||||
$path = $this->environmentConfigPath($name, $environment);
|
||||
$content = "<?php\n\n";
|
||||
$content .= "declare(strict_types=1);\n\n";
|
||||
$content .= 'return ' . $this->exportPhpValue($config) . ";\n";
|
||||
|
||||
if (file_put_contents($path, $content) === false) {
|
||||
throw new \RuntimeException('Konfigurationsdatei konnte nicht geschrieben werden.');
|
||||
}
|
||||
}
|
||||
|
||||
private function environmentConfigPath(string $name, string $environment): string
|
||||
{
|
||||
return $this->projectRoot . '/config/' . $environment . '/' . $name . '.php';
|
||||
}
|
||||
|
||||
private function exportPhpValue(mixed $value, int $depth = 0): string
|
||||
{
|
||||
if (is_array($value)) {
|
||||
if ($value === []) {
|
||||
return '[]';
|
||||
}
|
||||
|
||||
$indent = str_repeat(' ', $depth);
|
||||
$childIndent = str_repeat(' ', $depth + 1);
|
||||
$lines = ['['];
|
||||
|
||||
foreach ($value as $key => $item) {
|
||||
$prefix = is_int($key) ? '' : $this->exportPhpValue($key) . ' => ';
|
||||
$lines[] = $childIndent . $prefix . $this->exportPhpValue($item, $depth + 1) . ',';
|
||||
}
|
||||
|
||||
$lines[] = $indent . ']';
|
||||
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
return var_export($value, true);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,33 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
if (!function_exists('desktop_configure_session_storage')) {
|
||||
function desktop_configure_session_storage(): void
|
||||
{
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ini_get('session.save_handler') !== 'files') {
|
||||
return;
|
||||
}
|
||||
|
||||
$sessionPath = dirname(__DIR__, 2) . '/data/system/sessions';
|
||||
|
||||
if (!is_dir($sessionPath) && !mkdir($sessionPath, 0775, true) && !is_dir($sessionPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_writable($sessionPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ini_set('session.save_path', $sessionPath);
|
||||
}
|
||||
}
|
||||
|
||||
desktop_configure_session_storage();
|
||||
|
||||
spl_autoload_register(static function (string $class): void {
|
||||
$prefixes = [
|
||||
'App\\' => __DIR__ . '/',
|
||||
|
||||
Reference in New Issue
Block a user