(array $source)
| 381 | } |
| 382 | |
| 383 | public static function upsertSource(array $source): array |
| 384 | { |
| 385 | if (self::proSourcesAvailable()) { |
| 386 | return ProSources::upsertSource($source); |
| 387 | } |
| 388 | |
| 389 | $id = isset($source['id']) ? trim((string)$source['id']) : ''; |
| 390 | if ($id === '' || !preg_match('/^[A-Za-z0-9_-]{1,64}$/', $id)) { |
| 391 | return ['ok' => false, 'error' => 'Invalid source id']; |
| 392 | } |
| 393 | |
| 394 | $rawType = strtolower(trim((string)($source['type'] ?? 'local'))); |
| 395 | if (!self::isTypeAllowed($rawType)) { |
| 396 | return ['ok' => false, 'error' => 'Source type requires FileRise Pro']; |
| 397 | } |
| 398 | |
| 399 | $raw = self::loadRaw(); |
| 400 | $sourceMap = self::rawSourceMap($raw); |
| 401 | $existingRaw = isset($sourceMap[$id]) && is_array($sourceMap[$id]) ? $sourceMap[$id] : null; |
| 402 | $existing = is_array($existingRaw) ? self::normalizeSourceStored($existingRaw) : null; |
| 403 | |
| 404 | $normalized = self::normalizeSourceStored($source); |
| 405 | if (!$normalized) { |
| 406 | return ['ok' => false, 'error' => 'Invalid source configuration']; |
| 407 | } |
| 408 | |
| 409 | if (!array_key_exists('disableTrash', $source) && $existing && isset($existing['disableTrash'])) { |
| 410 | $normalized['disableTrash'] = !empty($existing['disableTrash']); |
| 411 | } |
| 412 | |
| 413 | if ($normalized['type'] === 'webdav') { |
| 414 | $cfgStore = $normalized['config']; |
| 415 | $password = isset($source['config']['password']) ? trim((string)$source['config']['password']) : ''; |
| 416 | |
| 417 | if ($password !== '') { |
| 418 | $cfgStore['passwordEnc'] = self::encryptSecret($password); |
| 419 | } elseif ( |
| 420 | $existingRaw |
| 421 | && isset($existingRaw['config']) |
| 422 | && is_array($existingRaw['config']) |
| 423 | && isset($existingRaw['config']['passwordEnc']) |
| 424 | ) { |
| 425 | $cfgStore['passwordEnc'] = (string)$existingRaw['config']['passwordEnc']; |
| 426 | } |
| 427 | |
| 428 | if (empty($cfgStore['passwordEnc'])) { |
| 429 | return ['ok' => false, 'error' => 'WebDAV requires a password']; |
| 430 | } |
| 431 | |
| 432 | $normalized['config'] = $cfgStore; |
| 433 | } |
| 434 | |
| 435 | $sourceMap[$id] = $normalized; |
| 436 | $raw['sources'] = $sourceMap; |
| 437 | |
| 438 | if (!self::saveRaw($raw)) { |
| 439 | return ['ok' => false, 'error' => 'Failed to save sources']; |
| 440 | } |
no test coverage detected