'; echo '

' . \esc_html__( 'Import Domain Blocklist', 'activitypub' ) . '

'; } /** * Display the importer footer. * * @return void */ private static function footer() { echo ''; } /** * Display the greeting/intro screen. * * @return void */ private static function greet() { echo '
'; echo '

' . \esc_html__( 'Import a domain blocklist to block multiple ActivityPub instances at once. Supported formats:', 'activitypub' ) . '

'; echo ''; // File upload option. \printf( '

%s

', \esc_html__( 'Option 1: Upload a File', 'activitypub' ) ); \wp_import_upload_form( 'admin.php?import=blocklist&step=1' ); // URL import option. \printf( '

%s

', \esc_html__( 'Option 2: Import from URL', 'activitypub' ) ); ?>

'; } /** * Handle file upload and import. * * @return void */ private static function handle_upload() { $error_message = \__( 'Sorry, there has been an error.', 'activitypub' ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified in dispatch(). if ( ! isset( $_FILES['import']['name'] ) ) { echo '

' . \esc_html( $error_message ) . '
'; \printf( /* translators: 1: php.ini, 2: post_max_size, 3: upload_max_filesize */ \esc_html__( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your %1$s file or by %2$s being defined as smaller than %3$s in %1$s.', 'activitypub' ), 'php.ini', 'post_max_size', 'upload_max_filesize' ); echo '

'; return; } // Allow CSV and TXT files. $allowed_types = array( 'csv' => 'text/csv', 'txt' => 'text/plain', ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified in dispatch(). $file_info = \wp_check_filetype( \sanitize_file_name( $_FILES['import']['name'] ), $allowed_types ); if ( ! $file_info['type'] ) { \printf( '

%s
%s

', \esc_html( $error_message ), \esc_html__( 'The uploaded file must be a CSV or TXT file. Please try again with the correct file format.', 'activitypub' ) ); return; } // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput -- Nonce verified in dispatch(), tmp_name is a server path. $file_path = $_FILES['import']['tmp_name'] ?? ''; if ( empty( $file_path ) ) { \printf( '

%s
%s

', \esc_html( $error_message ), \esc_html__( 'Upload failed. Please try again.', 'activitypub' ) ); return; } $domains = self::parse_csv( $file_path ); if ( empty( $domains ) ) { \printf( '

%s
%s

', \esc_html( $error_message ), \esc_html__( 'No valid domains found in the file.', 'activitypub' ) ); return; } self::import( $domains ); } /** * Handle URL import. * * @return void */ private static function handle_url_import() { $error_message = \__( 'Sorry, there has been an error.', 'activitypub' ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified in dispatch(). $url = \sanitize_url( \wp_unslash( $_POST['import_url'] ?? '' ) ); if ( empty( $url ) ) { \printf( '

%s
%s

', \esc_html( $error_message ), \esc_html__( 'Please provide a valid URL.', 'activitypub' ) ); return; } if ( ! \filter_var( $url, FILTER_VALIDATE_URL ) ) { \printf( '

%s
%s

', \esc_html( $error_message ), \esc_html__( 'The provided URL is not valid.', 'activitypub' ) ); return; } $result = Blocklist_Subscriptions::sync( $url ); if ( false === $result ) { \printf( '

%s
%s

', \esc_html( $error_message ), \esc_html__( 'Failed to fetch or parse the blocklist URL.', 'activitypub' ) ); return; } // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified in dispatch(). $subscribe = ! empty( $_POST['subscribe'] ); // Add subscription if requested (no need to sync again, just did it). $subscribed = $subscribe && Blocklist_Subscriptions::add( $url ); self::show_url_import_results( $result, $subscribed ); } /** * Execute the import for file uploads. * * @param array $domains Array of domains to import. * * @return void */ private static function import( $domains ) { \set_time_limit( 0 ); /** * Fires when the blocklist import starts. */ \do_action( 'import_start' ); $existing = Moderation::get_site_blocks()[ Moderation::TYPE_DOMAIN ] ?? array(); $new_domains = \array_diff( $domains, $existing ); $imported = \count( $new_domains ); $skipped = \count( $domains ) - $imported; Moderation::add_site_blocks( Moderation::TYPE_DOMAIN, $new_domains ); /** * Fires when the blocklist import ends. */ \do_action( 'import_end' ); echo '

' . \esc_html__( 'Import Complete', 'activitypub' ) . '

'; \printf( '

%s

', \esc_html( \sprintf( /* translators: %s: Number of domains */ \_n( 'Imported %s domain.', 'Imported %s domains.', $imported, 'activitypub' ), \number_format_i18n( $imported ) ) ) ); if ( $skipped > 0 ) { \printf( '

%s

', \esc_html( \sprintf( /* translators: %s: Number of domains */ \_n( 'Skipped %s domain (already blocked).', 'Skipped %s domains (already blocked).', $skipped, 'activitypub' ), \number_format_i18n( $skipped ) ) ) ); } \printf( '

%s

', \esc_url( \admin_url( 'options-general.php?page=activitypub&tab=settings' ) ), \esc_html__( 'View blocked domains in settings', 'activitypub' ) ); } /** * Show results for URL import. * * @param int $imported Number of domains imported. * @param bool $subscribed Whether the URL was subscribed to. * * @return void */ private static function show_url_import_results( $imported, $subscribed ) { echo '

' . \esc_html__( 'Import Complete', 'activitypub' ) . '

'; \printf( '

%s

', \esc_html( \sprintf( /* translators: %s: Number of domains */ \_n( 'Imported %s new domain.', 'Imported %s new domains.', $imported, 'activitypub' ), \number_format_i18n( $imported ) ) ) ); if ( $subscribed ) { echo '

' . \esc_html__( 'Subscribed for automatic weekly updates.', 'activitypub' ) . '

'; } \printf( '

%s

', \esc_url( \admin_url( 'options-general.php?page=activitypub&tab=settings' ) ), \esc_html__( 'View blocked domains in settings', 'activitypub' ) ); } /** * Parse a CSV file and extract domain names. * * @param string $file_path Path to the CSV file. * @return array Array of unique, valid domain names. */ public static function parse_csv( $file_path ) { if ( ! \file_exists( $file_path ) || ! \is_readable( $file_path ) ) { return array(); } // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- Reading local file. $content = \file_get_contents( $file_path ); if ( false === $content ) { return array(); } return Blocklist_Subscriptions::parse_csv_string( $content ); } }