diff --git a/include/nc_connector_webdav.inc.php b/include/nc_connector_webdav.inc.php index e4b5596..4c23270 100644 --- a/include/nc_connector_webdav.inc.php +++ b/include/nc_connector_webdav.inc.php @@ -5,46 +5,24 @@ if (!defined('PHPWG_ROOT_PATH')) } /** - * Return the only existing local connector as migration fallback. + * Link a WebDAV successor with the exact legacy connection selected for migration. */ -function bratonien_tools_nc_connector_single_local_fallback() +function bratonien_tools_nc_connector_pair_migration_fallback($legacy_id, $webdav_id, array &$webdav_config, $now) { - bratonien_tools_nc_connector_ensure_table(); - $table = bratonien_tools_nc_connector_table(); - $result = pwg_query("SELECT id, enabled, takeover_state, config_json FROM `$table` WHERE adapter='local' ORDER BY id"); - $rows = array(); - - while ($row = pwg_db_fetch_assoc($result)) + $legacy_id = (int)$legacy_id; + $webdav_id = (int)$webdav_id; + if ($legacy_id < 1 || $webdav_id < 1 || $legacy_id === $webdav_id) { - $rows[] = $row; - if (count($rows) > 1) return null; + throw new RuntimeException('Die Migrationszuordnung ist ungueltig.'); } - if (count($rows) !== 1) return null; - - $row = $rows[0]; - $config = json_decode((string)$row['config_json'], true); - if (!is_array($config)) $config = array(); - - return array( - 'id'=>(int)$row['id'], - 'enabled'=>(bool)$row['enabled'], - 'takeover_state'=>(string)$row['takeover_state'], - 'config'=>$config, - ); -} - -/** - * Link a WebDAV connection with the single existing local fallback. - */ -function bratonien_tools_nc_connector_pair_migration_fallback($webdav_id, array &$webdav_config, $now) -{ - $legacy = bratonien_tools_nc_connector_single_local_fallback(); - if (!$legacy) return null; - - $legacy_id = (int)$legacy['id']; - if ($legacy_id < 1 || $legacy_id === (int)$webdav_id) return null; + $legacy = bratonien_tools_nc_connector_connection($legacy_id, false); + if (!$legacy || (string)$legacy['adapter'] !== 'local') + { + throw new RuntimeException('Die ausgewaehlte Legacy-Verbindung fuer die Migration ist nicht mehr verfuegbar.'); + } + $legacy_config = isset($legacy['config']) && is_array($legacy['config']) ? $legacy['config'] : array(); $webdav_config['migration'] = array( 'role'=>'webdav-primary-candidate', 'legacy_fallback_connection_id'=>$legacy_id, @@ -52,11 +30,9 @@ function bratonien_tools_nc_connector_pair_migration_fallback($webdav_id, array 'paired_at'=>(string)$now, 'cutover_state'=>'parallel', ); - - $legacy_config = $legacy['config']; $legacy_config['migration'] = array( 'role'=>'legacy-fallback', - 'webdav_successor_connection_id'=>(int)$webdav_id, + 'webdav_successor_connection_id'=>$webdav_id, 'fallback_policy'=>'keep-running', 'paired_at'=>(string)$now, 'cutover_state'=>'parallel', @@ -69,7 +45,7 @@ function bratonien_tools_nc_connector_pair_migration_fallback($webdav_id, array } $table = bratonien_tools_nc_connector_table(); - pwg_query("UPDATE `$table` SET config_json='".pwg_db_real_escape_string($legacy_json)."', updated='".pwg_db_real_escape_string((string)$now)."' WHERE id=".$legacy_id." LIMIT 1"); + pwg_query("UPDATE `$table` SET config_json='".pwg_db_real_escape_string($legacy_json)."', updated='".pwg_db_real_escape_string((string)$now)."' WHERE id=".$legacy_id." AND adapter='local' LIMIT 1"); return $legacy_id; } @@ -77,9 +53,8 @@ function bratonien_tools_nc_connector_pair_migration_fallback($webdav_id, array /** * Create or update a WebDAV-backed connector from the user-facing wizard. * - * Remote connections are updated in place. When the editor was opened for a - * legacy connection, a WebDAV successor is created and the legacy connection - * stays available as fallback. + * Remote connections are updated in place. A legacy connection is paired only + * when the wizard was explicitly opened in migration mode for that connection. */ function bratonien_tools_nc_connector_create_webdav_placeholder_from_wizard() { @@ -87,7 +62,7 @@ function bratonien_tools_nc_connector_create_webdav_placeholder_from_wizard() if (empty($state['scan_ok']) || empty($state['technical_complete'])) { - throw new RuntimeException('Die WebDAV-Verbindung wurde im Assistenten noch nicht vollständig vorbereitet.'); + throw new RuntimeException('Die WebDAV-Verbindung wurde im Assistenten noch nicht vollstaendig vorbereitet.'); } $base_url = rtrim(trim((string)($state['base_url'] ?? '')), '/'); @@ -95,7 +70,7 @@ function bratonien_tools_nc_connector_create_webdav_placeholder_from_wizard() $password = (string)($state['_password'] ?? ''); if ($base_url === '' || $username === '' || $password === '') { - throw new RuntimeException('Für den WebDAV-Zugang fehlen Nextcloud-Adresse oder Zugangsdaten.'); + throw new RuntimeException('Fuer den WebDAV-Zugang fehlen Nextcloud-Adresse oder Zugangsdaten.'); } $selected = isset($state['directory_selected']) && is_array($state['directory_selected']) @@ -104,13 +79,13 @@ function bratonien_tools_nc_connector_create_webdav_placeholder_from_wizard() $selected_ids = isset($state['directory_selected_fileids']) && is_array($state['directory_selected_fileids']) ? $state['directory_selected_fileids'] : array(); - if (!$selected) throw new RuntimeException('Bitte mindestens ein Nextcloud-Verzeichnis auswählen.'); + if (!$selected) throw new RuntimeException('Bitte mindestens ein Nextcloud-Verzeichnis auswaehlen.'); $roots = array(); foreach ($selected as $path) { $fileid = isset($selected_ids[$path]) ? (int)$selected_ids[$path] : 0; - if ($fileid < 1) throw new RuntimeException('Für ein ausgewähltes Nextcloud-Verzeichnis fehlt die eindeutige Datei-ID.'); + if ($fileid < 1) throw new RuntimeException('Fuer ein ausgewaehltes Nextcloud-Verzeichnis fehlt die eindeutige Datei-ID.'); $display_name = $path === '' ? (trim((string)($state['display_name'] ?? '')) !== '' ? trim((string)$state['display_name']) : $username) : basename($path); @@ -139,6 +114,14 @@ function bratonien_tools_nc_connector_create_webdav_placeholder_from_wizard() && (string)$editing_connection['adapter'] === 'remote' && (string)($editing_connection['config']['source_mode'] ?? '') === 'webdav-placeholder' && $editing_mode === 'update'; + $migrating_legacy = $editing_connection + && (string)$editing_connection['adapter'] === 'local' + && $editing_mode === 'migrate'; + + if ($editing_mode === 'migrate' && !$migrating_legacy) + { + throw new RuntimeException('Die fuer die Migration ausgewaehlte Legacy-Verbindung ist nicht mehr verfuegbar.'); + } $config = array( 'origin'=>'native', @@ -202,12 +185,12 @@ function bratonien_tools_nc_connector_create_webdav_placeholder_from_wizard() $config_json = json_encode($config, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); if (!is_string($config_json)) throw new RuntimeException('WebDAV-Konfiguration konnte nicht serialisiert werden.'); - pwg_query("UPDATE `$table` SET name='".pwg_db_real_escape_string($name)."', config_json='".pwg_db_real_escape_string($config_json)."', secret_blob='".pwg_db_real_escape_string($secret_blob)."', updated='".pwg_db_real_escape_string($now)."' WHERE id=".$editing_id." LIMIT 1"); + pwg_query("UPDATE `$table` SET name='".pwg_db_real_escape_string($name)."', config_json='".pwg_db_real_escape_string($config_json)."', secret_blob='".pwg_db_real_escape_string($secret_blob)."', updated='".pwg_db_real_escape_string($now)."' WHERE id=".$editing_id." AND adapter='remote' LIMIT 1"); unset($_SESSION['bratonien_nc_wizard']); return array( 'connection_id'=>$editing_id, - 'message'=>'WebDAV-Verbindung #'.$editing_id.' wurde gespeichert. Der nächste Connector-Lauf verwendet die neuen Einstellungen.', + 'message'=>'WebDAV-Verbindung #'.$editing_id.' wurde gespeichert. Der naechste Connector-Lauf verwendet die neuen Einstellungen.', ); } @@ -226,22 +209,26 @@ function bratonien_tools_nc_connector_create_webdav_placeholder_from_wizard() $id = (int)pwg_db_insert_id(); if ($id < 1) throw new RuntimeException('Die WebDAV-Verbindung konnte nicht eindeutig angelegt werden.'); + $legacy_fallback_id = null; try { $config['state_dir'] = '/var/lib/bratonien-tools/nc-connector/connection-'.$id; $config['status_file'] = $config['state_dir'].'/connector-status.json'; - $legacy_fallback_id = bratonien_tools_nc_connector_pair_migration_fallback($id, $config, $now); + if ($migrating_legacy) + { + $legacy_fallback_id = bratonien_tools_nc_connector_pair_migration_fallback($editing_id, $id, $config, $now); + } $config_json = json_encode($config, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); if (!is_string($config_json)) { throw new RuntimeException('Die WebDAV-Verbindung konnte nach dem Anlegen nicht serialisiert werden.'); } - pwg_query("UPDATE `$table` SET config_json='".pwg_db_real_escape_string($config_json)."' WHERE id=".$id." LIMIT 1"); + pwg_query("UPDATE `$table` SET config_json='".pwg_db_real_escape_string($config_json)."' WHERE id=".$id." AND adapter='remote' LIMIT 1"); } catch (Throwable $e) { - pwg_query("DELETE FROM `$table` WHERE id=".$id." LIMIT 1"); + pwg_query("DELETE FROM `$table` WHERE id=".$id." AND adapter='remote' LIMIT 1"); throw $e; }