diff --git a/src/Admin/ConnectionTestController.php b/src/Admin/ConnectionTestController.php new file mode 100644 index 0000000..598da3c --- /dev/null +++ b/src/Admin/ConnectionTestController.php @@ -0,0 +1,100 @@ +settings_repository = $settings_repository; + $this->transport_client = $transport_client; + $this->logger = $logger; + } + + public function register(): void { + add_action( 'admin_post_wpcs_test_connection', array( $this, 'handleTest' ) ); + } + + public function handleTest(): void { + if ( ! current_user_can( 'manage_options' ) ) { + throw new \RuntimeException( 'You do not have permission to test WP Content Sync connections.' ); + } + + if ( ! check_admin_referer( 'wpcs_test_connection', 'wpcs_connection_nonce' ) ) { + throw new \RuntimeException( 'The connection test request could not be verified.' ); + } + + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified above. + $pair_index = isset( $_POST['pair_index'] ) ? max( 0, (int) sanitize_text_field( wp_unslash( $_POST['pair_index'] ) ) ) : 0; + $pairs = $this->settings_repository->get()->syncPairs(); + $pair = $pairs[ $pair_index ] ?? null; + + if ( ! is_array( $pair ) ) { + $this->redirectWithError( 'The selected sync pair could not be found.' ); + return; + } + + try { + $this->transport_client->testConnection( + (string) $pair['destination_url'], + (string) $pair['username'], + (string) $pair['application_password'] + ); + + $this->logger->info( + 'REST connection test succeeded.', + array( + 'pair_index' => $pair_index, + 'destination_url' => (string) $pair['destination_url'], + 'username' => (string) $pair['username'], + ) + ); + + wp_safe_redirect( + add_query_arg( + array( 'wpcs_connection_ok' => '1' ), + admin_url( 'admin.php?page=wp-content-sync' ) + ) + ); + } catch ( RestTransportException $exception ) { + $this->logger->warning( + 'REST connection test failed.', + array( + 'pair_index' => $pair_index, + 'destination_url' => (string) $pair['destination_url'], + 'username' => (string) $pair['username'], + 'failure_code' => $exception->failureCode(), + ) + ); + + $this->redirectWithError( $exception->getMessage() ); + } + } + + private function redirectWithError( string $message ): void { + wp_safe_redirect( + add_query_arg( + array( 'wpcs_connection_error' => sanitize_text_field( $message ) ), + admin_url( 'admin.php?page=wp-content-sync' ) + ) + ); + } +} diff --git a/src/Plugin.php b/src/Plugin.php index b37c33c..243b7e4 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -8,6 +8,7 @@ namespace WPContentSync; use WPContentSync\Admin\AdminPage; +use WPContentSync\Admin\ConnectionTestController; use WPContentSync\Admin\FileImportController; use WPContentSync\Admin\SettingsController; use WPContentSync\Content\ContentHandlerRegistry; @@ -186,6 +187,17 @@ final class Plugin { } ); + $container->factory( + ConnectionTestController::class, + static function () use ( $container ): ConnectionTestController { + return new ConnectionTestController( + $container->get( SettingsRepository::class ), + $container->get( RestTransportClient::class ), + $container->get( LoggerInterface::class ) + ); + } + ); + $container->factory( RestPackageController::class, static function () use ( $container ): RestPackageController { @@ -222,9 +234,13 @@ final class Plugin { /** @var SettingsController $settings_controller */ $settings_controller = $this->container->get( SettingsController::class ); + /** @var ConnectionTestController $connection_test_controller */ + $connection_test_controller = $this->container->get( ConnectionTestController::class ); + $admin_page->register(); $file_import_controller->register(); $rest_package_controller->register(); $settings_controller->register(); + $connection_test_controller->register(); } } diff --git a/templates/admin/dashboard.php b/templates/admin/dashboard.php index 8c405ea..b93d458 100644 --- a/templates/admin/dashboard.php +++ b/templates/admin/dashboard.php @@ -51,6 +51,20 @@ if ( array() === $sync_pairs ) { + + +