From a88d5c357d13a2f7e6bd28b4d8a1c4f87c9fe13e Mon Sep 17 00:00:00 2001 From: Imants Date: Thu, 11 Dec 2025 23:56:55 +0200 Subject: [PATCH 01/10] fix: add translators comments and escape ajax messages --- src/php/admin-menus/class-import-menu.php | 54 +++++++++++++---------- src/php/settings/class-version-switch.php | 23 +++++----- 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src/php/admin-menus/class-import-menu.php b/src/php/admin-menus/class-import-menu.php index 3c3b2565..5c018342 100644 --- a/src/php/admin-menus/class-import-menu.php +++ b/src/php/admin-menus/class-import-menu.php @@ -128,30 +128,36 @@ protected function print_messages() { echo '

'; } - if ( isset( $_REQUEST['imported'] ) ) { - echo '

'; - - $imported = intval( $_REQUEST['imported'] ); - - if ( 0 === $imported ) { - esc_html_e( 'No snippets were imported.', 'code-snippets' ); - - } else { - /* translators: %d: amount of snippets imported */ - printf( - _n( - 'Successfully imported %d snippet.', - 'Successfully imported %d snippets.', - $imported, - 'code-snippets' - ), - '' . number_format_i18n( $imported ) . '', - ); - - printf( - ' %s', - esc_url( code_snippets()->get_menu_url( 'manage' ) ), - esc_html__( 'Have fun!', 'code-snippets' ) + if ( isset( $_REQUEST['imported'] ) ) { + echo '

'; + + $imported = intval( $_REQUEST['imported'] ); + + if ( 0 === $imported ) { + esc_html_e( 'No snippets were imported.', 'code-snippets' ); + + } else { + $imported_count = sprintf( '%s', esc_html( number_format_i18n( $imported ) ) ); + printf( + '%s', + wp_kses_post( + sprintf( + /* translators: %s: number of snippets imported. */ + _n( + 'Successfully imported %s snippet.', + 'Successfully imported %s snippets.', + $imported, + 'code-snippets' + ), + $imported_count + ) + ) + ); + + printf( + ' %s', + esc_url( code_snippets()->get_menu_url( 'manage' ) ), + esc_html__( 'Have fun!', 'code-snippets' ) ); } diff --git a/src/php/settings/class-version-switch.php b/src/php/settings/class-version-switch.php index b2486e1c..c1ef11e7 100644 --- a/src/php/settings/class-version-switch.php +++ b/src/php/settings/class-version-switch.php @@ -230,17 +230,18 @@ public static function handle_version_switch( string $target_version ): array { return self::create_error_response( $install_result->get_error_message() ); } - if ( $install_result ) { - delete_transient( VERSION_CACHE_KEY ); + if ( $install_result ) { + delete_transient( VERSION_CACHE_KEY ); - return [ - 'success' => true, - 'message' => sprintf( __( 'Successfully switched to version %s. Please refresh the page to see changes.', 'code-snippets' ), $target_version ), - ]; - } + return [ + 'success' => true, + /* translators: %s: the version number that was switched to. */ + 'message' => sprintf( __( 'Successfully switched to version %s. Please refresh the page to see changes.', 'code-snippets' ), $target_version ), + ]; + } - return self::handle_installation_failure( $target_version, $validation['download_url'], $install_result ); - } + return self::handle_installation_failure( $target_version, $validation['download_url'], $install_result ); + } public static function render_version_switch_field( array $args ): void { $current_version = self::get_current_version(); @@ -291,7 +292,7 @@ public static function render_version_switch_field( array $args ): void { public static function ajax_switch_version(): void { if ( ! wp_verify_nonce( $_POST['nonce'] ?? '', 'code_snippets_version_switch' ) ) { - wp_die( __( 'Security check failed.', 'code-snippets' ) ); + wp_die( esc_html__( 'Security check failed.', 'code-snippets' ) ); } if ( ! current_user_can( 'update_plugins' ) ) { @@ -329,7 +330,7 @@ public static function render_refresh_versions_field( array $args ): void { public static function ajax_refresh_versions(): void { if ( ! wp_verify_nonce( $_POST['nonce'] ?? '', 'code_snippets_refresh_versions' ) ) { - wp_die( __( 'Security check failed.', 'code-snippets' ) ); + wp_die( esc_html__( 'Security check failed.', 'code-snippets' ) ); } if ( ! current_user_can( 'manage_options' ) ) { From e3600f8d8a9c7556b9b7274d7b24d395fc627d72 Mon Sep 17 00:00:00 2001 From: Imants Date: Thu, 11 Dec 2025 23:57:00 +0200 Subject: [PATCH 02/10] fix: translators comments for list views and notices --- src/php/class-list-table.php | 76 ++++++++++--------- src/php/views/partials/list-table-notices.php | 54 ++++++------- 2 files changed, 68 insertions(+), 62 deletions(-) diff --git a/src/php/class-list-table.php b/src/php/class-list-table.php index 41ed1379..bdae02de 100644 --- a/src/php/class-list-table.php +++ b/src/php/class-list-table.php @@ -618,17 +618,21 @@ public function get_views(): array { continue 2; } - $shared_label_template = $this->is_network - ? _n_noop( + if ( $this->is_network ) { + /* translators: %s: total number of snippets shared with subsites. */ + $shared_label_template = _n_noop( 'Shared with Subsites (%s)', 'Shared with Subsites (%s)', 'code-snippets' - ) - : _n_noop( + ); + } else { + /* translators: %s: total number of network snippets. */ + $shared_label_template = _n_noop( 'Network Snippets (%s)', 'Network Snippets (%s)', 'code-snippets' ); + } $template = translate_nooped_plural( $shared_label_template, $count, 'code-snippets' ); break; @@ -663,16 +667,16 @@ public function get_views(): array { * @since 2.0 */ public function get_current_tags() { - global $snippets, $status; + global $code_snippets_snippets, $status; // If we're not viewing a snippets table, get all used tags instead. - if ( ! isset( $snippets, $status ) ) { + if ( ! isset( $code_snippets_snippets, $status ) ) { $tags = get_all_snippet_tags(); } else { $tags = array(); // Merge all tags into a single array. - foreach ( $snippets[ $status ] as $snippet ) { + foreach ( $code_snippets_snippets[ $status ] as $snippet ) { $tags = array_merge( $snippet->tags, $tags ); } @@ -1088,12 +1092,12 @@ public function prepare_items() { /** * Global variables. * - * @var string $status Current status view. - * @var array $snippets List of snippets for views. - * @var array $totals List of total items for views. - * @var string $s Current search term. + * @var string $status Current status view. + * @var array $code_snippets_snippets List of snippets for views. + * @var array $totals List of total items for views. + * @var string $s Current search term. */ - global $status, $snippets, $totals, $s; + global $status, $code_snippets_snippets, $totals, $s; wp_reset_vars( array( 'orderby', 'order', 's' ) ); @@ -1107,21 +1111,21 @@ public function prepare_items() { } $this->process_requested_actions(); - $snippets = array_fill_keys( $this->statuses, array() ); + $code_snippets_snippets = array_fill_keys( $this->statuses, array() ); $all_snippets = apply_filters( 'code_snippets/list_table/get_snippets', $this->fetch_shared_network_snippets( get_snippets() ) ); // Separate trashed snippets from the main collection - $snippets['trashed'] = array_filter( $all_snippets, function( $snippet ) { + $code_snippets_snippets['trashed'] = array_filter( $all_snippets, function( $snippet ) { return $snippet->is_trashed(); }); // Filter out trashed snippets from the 'all' collection - $snippets['all'] = array_filter( $all_snippets, function( $snippet ) { + $code_snippets_snippets['all'] = array_filter( $all_snippets, function( $snippet ) { return ! $snippet->is_trashed(); }); - foreach ( $snippets['all'] as $snippet ) { + foreach ( $code_snippets_snippets['all'] as $snippet ) { if ( $snippet->active ) { $this->active_by_condition[ $snippet->condition_id ][] = $snippet; } @@ -1131,16 +1135,16 @@ public function prepare_items() { $type = sanitize_key( wp_unslash( $_GET['type'] ?? '' ) ); if ( $type && 'all' !== $type ) { - $snippets['all'] = array_filter( - $snippets['all'], + $code_snippets_snippets['all'] = array_filter( + $code_snippets_snippets['all'], function ( Snippet $snippet ) use ( $type ) { return $type === $snippet->type; } ); // Filter trashed snippets by type - $snippets['trashed'] = array_filter( - $snippets['trashed'], + $code_snippets_snippets['trashed'] = array_filter( + $code_snippets_snippets['trashed'], function ( Snippet $snippet ) use ( $type ) { return $type === $snippet->type; } @@ -1148,13 +1152,13 @@ function ( Snippet $snippet ) use ( $type ) { } // Add scope tags to all snippets (including trashed). - foreach ( $snippets['all'] as $snippet ) { + foreach ( $code_snippets_snippets['all'] as $snippet ) { if ( 'global' !== $snippet->scope ) { $snippet->add_tag( $snippet->scope ); } } - foreach ( $snippets['trashed'] as $snippet ) { + foreach ( $code_snippets_snippets['trashed'] as $snippet ) { if ( 'global' !== $snippet->scope ) { $snippet->add_tag( $snippet->scope ); } @@ -1162,27 +1166,27 @@ function ( Snippet $snippet ) use ( $type ) { // Filter snippets by tag. if ( ! empty( $_GET['tag'] ) ) { - $snippets['all'] = array_filter( $snippets['all'], array( $this, 'tags_filter_callback' ) ); - $snippets['trashed'] = array_filter( $snippets['trashed'], array( $this, 'tags_filter_callback' ) ); + $code_snippets_snippets['all'] = array_filter( $code_snippets_snippets['all'], array( $this, 'tags_filter_callback' ) ); + $code_snippets_snippets['trashed'] = array_filter( $code_snippets_snippets['trashed'], array( $this, 'tags_filter_callback' ) ); } // Filter snippets based on search query. if ( $s ) { - $snippets['all'] = array_filter( $snippets['all'], array( $this, 'search_by_line_callback' ) ); - $snippets['trashed'] = array_filter( $snippets['trashed'], array( $this, 'search_by_line_callback' ) ); + $code_snippets_snippets['all'] = array_filter( $code_snippets_snippets['all'], array( $this, 'search_by_line_callback' ) ); + $code_snippets_snippets['trashed'] = array_filter( $code_snippets_snippets['trashed'], array( $this, 'search_by_line_callback' ) ); } if ( is_multisite() ) { - $snippets['shared_network'] = array_values( + $code_snippets_snippets['shared_network'] = array_values( array_filter( - $snippets['all'], + $code_snippets_snippets['all'], static function ( Snippet $snippet ) { return $snippet->shared_network; } ) ); } else { - $snippets['shared_network'] = array(); + $code_snippets_snippets['shared_network'] = array(); } // Clear recently activated snippets older than a week. @@ -1205,20 +1209,20 @@ static function ( Snippet $snippet ) { * * @var Snippet $snippet */ - foreach ( $snippets['all'] as $snippet ) { + foreach ( $code_snippets_snippets['all'] as $snippet ) { // Skip trashed snippets (they're already in their own section) if ( $snippet->is_trashed() ) { continue; } if ( $snippet->active || $this->is_condition_active( $snippet ) ) { - $snippets['active'][] = $snippet; + $code_snippets_snippets['active'][] = $snippet; } else { - $snippets['inactive'][] = $snippet; + $code_snippets_snippets['inactive'][] = $snippet; // Was the snippet recently deactivated? if ( isset( $recently_activated[ $snippet->id ] ) ) { - $snippets['recently_activated'][] = $snippet; + $code_snippets_snippets['recently_activated'][] = $snippet; } } } @@ -1228,16 +1232,16 @@ static function ( Snippet $snippet ) { function ( $section_snippets ) { return count( $section_snippets ); }, - $snippets + $code_snippets_snippets ); // If the current status is empty, default to all. - if ( empty( $snippets[ $status ] ) ) { + if ( empty( $code_snippets_snippets[ $status ] ) ) { $status = 'all'; } // Get the current data. - $data = $snippets[ $status ]; + $data = $code_snippets_snippets[ $status ]; // Decide how many records per page to show by getting the user's setting in the Screen Options panel. $sort_by = $this->screen->get_option( 'per_page', 'option' ); diff --git a/src/php/views/partials/list-table-notices.php b/src/php/views/partials/list-table-notices.php index c3d34561..56becfc7 100644 --- a/src/php/views/partials/list-table-notices.php +++ b/src/php/views/partials/list-table-notices.php @@ -21,14 +21,14 @@ */ if ( defined( 'CODE_SNIPPETS_SAFE_MODE' ) && CODE_SNIPPETS_SAFE_MODE ) { ?> -

-

- - CODE_SNIPPETS_SAFE_MODE', 'wp-config.php' ); - ?> +

+

+ + CODE_SNIPPETS_SAFE_MODE', 'wp-config.php' ); + ?> @@ -42,9 +42,9 @@ return; } -$result = sanitize_key( $_REQUEST['result'] ); +$code_snippets_result = sanitize_key( $_REQUEST['result'] ); -$result_messages = [ +$code_snippets_result_messages = [ 'executed' => __( 'Snippet executed.', 'code-snippets' ), 'activated' => __( 'Snippet activated.', 'code-snippets' ), 'activated-multi' => __( 'Selected snippets activated.', 'code-snippets' ), @@ -62,43 +62,45 @@ ]; // Add undo link for single snippet trash action -if ( 'deleted' === $result && ! empty( $_REQUEST['ids'] ) ) { - $deleted_ids = sanitize_text_field( $_REQUEST['ids'] ); - $undo_url = wp_nonce_url( +if ( 'deleted' === $code_snippets_result && ! empty( $_REQUEST['ids'] ) ) { + $code_snippets_deleted_ids = sanitize_text_field( $_REQUEST['ids'] ); + $code_snippets_undo_url = wp_nonce_url( add_query_arg( array( 'action' => 'restore', - 'ids' => $deleted_ids + 'ids' => $code_snippets_deleted_ids ) ), 'bulk-snippets' ); - $result_messages['deleted'] = sprintf( + $code_snippets_result_messages['deleted'] = sprintf( + /* translators: %s: URL to undo snippet deletion. */ __( 'Snippet trashed. Undo', 'code-snippets' ), - esc_url( $undo_url ) + esc_url( $code_snippets_undo_url ) ); } // Add undo link for bulk snippet trash action -if ( 'deleted-multi' === $result && ! empty( $_REQUEST['ids'] ) ) { - $deleted_ids = sanitize_text_field( $_REQUEST['ids'] ); - $undo_url = wp_nonce_url( +if ( 'deleted-multi' === $code_snippets_result && ! empty( $_REQUEST['ids'] ) ) { + $code_snippets_deleted_ids = sanitize_text_field( $_REQUEST['ids'] ); + $code_snippets_undo_url = wp_nonce_url( add_query_arg( array( 'action' => 'restore', - 'ids' => $deleted_ids + 'ids' => $code_snippets_deleted_ids ) ), 'bulk-snippets' ); - $result_messages['deleted-multi'] = sprintf( + $code_snippets_result_messages['deleted-multi'] = sprintf( + /* translators: %s: URL to undo snippet deletion. */ __( 'Selected snippets trashed. Undo', 'code-snippets' ), - esc_url( $undo_url ) + esc_url( $code_snippets_undo_url ) ); } -$result_messages = apply_filters( 'code_snippets/manage/result_messages', $result_messages ); +$code_snippets_result_messages = apply_filters( 'code_snippets/manage/result_messages', $code_snippets_result_messages ); -if ( isset( $result_messages[ $result ] ) ) { - $result_kses = [ +if ( isset( $code_snippets_result_messages[ $code_snippets_result ] ) ) { + $code_snippets_result_kses = [ 'strong' => [], 'a' => [ 'href' => [], @@ -107,6 +109,6 @@ printf( '

%s

', - wp_kses( $result_messages[ $result ], $result_kses ) + wp_kses( $code_snippets_result_messages[ $code_snippets_result ], $code_snippets_result_kses ) ); } From 4e7ebce0afa9676ead62f6161b47ca36b634612f Mon Sep 17 00:00:00 2001 From: Imants Date: Thu, 11 Dec 2025 23:57:09 +0200 Subject: [PATCH 03/10] fix: escape cloud list action links --- src/php/cloud/class-cloud-search-list-table.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/php/cloud/class-cloud-search-list-table.php b/src/php/cloud/class-cloud-search-list-table.php index af1051c7..db8040f0 100644 --- a/src/php/cloud/class-cloud-search-list-table.php +++ b/src/php/cloud/class-cloud-search-list-table.php @@ -173,11 +173,11 @@ public function display_rows() { echo ''; ?> - -
    - -
-
+ +
    + +
+

process_description( $item->description ) ); ?>

From bd21d1556d5e3031ae10462e8e691fde9530792d Mon Sep 17 00:00:00 2001 From: Imants Date: Thu, 11 Dec 2025 23:57:15 +0200 Subject: [PATCH 04/10] fix: prefix globals in loader and manage view --- src/php/load.php | 14 +++++----- src/php/views/manage.php | 60 ++++++++++++++++++++-------------------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/php/load.php b/src/php/load.php index de46e383..a3b37470 100644 --- a/src/php/load.php +++ b/src/php/load.php @@ -50,15 +50,15 @@ // Since Imposter rewrites namespaces to Code_Snippets\Vendor\*, we need to remove the original PSR-4 // mappings that Composer generates so other plugins can load their own copies of these libraries. if ( $code_snippets_autoloader instanceof \Composer\Autoload\ClassLoader ) { - $prefixes = $code_snippets_autoloader->getPrefixesPsr4(); - $our_prefix = 'Code_Snippets\\Vendor\\'; + $code_snippets_prefixes = $code_snippets_autoloader->getPrefixesPsr4(); + $code_snippets_vendor_prefix = 'Code_Snippets\\Vendor\\'; - foreach ( $prefixes as $namespace => $paths ) { + foreach ( $code_snippets_prefixes as $code_snippets_namespace => $code_snippets_paths ) { // Remove any non-Code_Snippets namespace that has a corresponding prefixed version - if ( strpos( $namespace, $our_prefix ) === false ) { - $prefixed_namespace = $our_prefix . $namespace; - if ( isset( $prefixes[ $prefixed_namespace ] ) ) { - $code_snippets_autoloader->setPsr4( $namespace, [] ); + if ( strpos( $code_snippets_namespace, $code_snippets_vendor_prefix ) === false ) { + $code_snippets_prefixed_namespace = $code_snippets_vendor_prefix . $code_snippets_namespace; + if ( isset( $code_snippets_prefixes[ $code_snippets_prefixed_namespace ] ) ) { + $code_snippets_autoloader->setPsr4( $code_snippets_namespace, [] ); } } } diff --git a/src/php/views/manage.php b/src/php/views/manage.php index 5b0b7194..2eb98b31 100644 --- a/src/php/views/manage.php +++ b/src/php/views/manage.php @@ -20,8 +20,8 @@ return; } -$types = array_merge( [ 'all' => __( 'All Snippets', 'code-snippets' ) ], Plugin::get_types() ); -$current_type = $this->get_current_type(); +$code_snippets_types = array_merge( [ 'all' => __( 'All Snippets', 'code-snippets' ) ], Plugin::get_types() ); +$code_snippets_current_type = $this->get_current_type(); if ( false !== strpos( code_snippets()->version, 'beta' ) ) { echo '

'; @@ -54,9 +54,9 @@ print_messages(); ?>

From fd1ed584e1d89350b174c2f0f417c7db4d296ec2 Mon Sep 17 00:00:00 2001 From: Imants Date: Thu, 11 Dec 2025 23:57:21 +0200 Subject: [PATCH 05/10] fix: prefix globals in import and cloud search views --- src/php/views/import.php | 49 +++++++++++++------------ src/php/views/partials/cloud-search.php | 44 +++++++++++----------- 2 files changed, 47 insertions(+), 46 deletions(-) diff --git a/src/php/views/import.php b/src/php/views/import.php index 902d4409..f4548ea7 100644 --- a/src/php/views/import.php +++ b/src/php/views/import.php @@ -18,7 +18,8 @@ return; } -$max_size_bytes = apply_filters( 'import_upload_size_limit', wp_max_upload_size() ); +// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Core hook name expected by WordPress importers. +$code_snippets_max_size_bytes = apply_filters( 'import_upload_size_limit', wp_max_upload_size() ); ?>
@@ -40,18 +41,18 @@

-

- All Snippets page to activate the imported snippets.', 'code-snippets' ); - $url = esc_url( code_snippets()->get_menu_url( 'manage' ) ); - - echo wp_kses( - sprintf( $text, $url ), - array( - 'a' => array( - 'href' => array(), - 'target' => array(), +

+ All Snippets page to activate the imported snippets.', 'code-snippets' ); + $code_snippets_manage_url = esc_url( code_snippets()->get_menu_url( 'manage' ) ); + + echo wp_kses( + sprintf( $code_snippets_import_notice, $code_snippets_manage_url ), + array( + 'a' => array( + 'href' => array(), + 'target' => array(), ), ) ); @@ -98,17 +99,17 @@

-

- - - - - -

-
+

+ + + + + +

+ @@ -30,32 +30,32 @@
- ', esc_attr( sanitize_text_field( wp_unslash( $_REQUEST['type'] ) ) ) ); + + + ', esc_attr( sanitize_text_field( wp_unslash( $_REQUEST['type'] ) ) ) ); } ?>

-
-
- - +
+
+ + - @@ -68,7 +68,7 @@ cloud_search_list_table->display(); } From d9c4c6617d088777f049826c8174edbb6cbf4e94 Mon Sep 17 00:00:00 2001 From: Imants Date: Thu, 11 Dec 2025 23:57:26 +0200 Subject: [PATCH 06/10] fix: prefix globals in welcome and mce strings --- src/php/front-end/mce-strings.php | 2 + src/php/views/welcome.php | 88 +++++++++++++++---------------- 2 files changed, 46 insertions(+), 44 deletions(-) diff --git a/src/php/front-end/mce-strings.php b/src/php/front-end/mce-strings.php index 58ceef03..6395637f 100644 --- a/src/php/front-end/mce-strings.php +++ b/src/php/front-end/mce-strings.php @@ -9,6 +9,7 @@ use _WP_Editors; +/* phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound */ /** * Variable types. * @@ -53,3 +54,4 @@ $strings = [ _WP_Editors::$mce_locale => [ 'code_snippets' => $strings ] ]; /** $strings is used by outer file. @noinspection PhpUnusedLocalVariableInspection */ $strings = 'tinyMCE.addI18n(' . wp_json_encode( $strings ) . ');'; +/* phpcs:enable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound */ diff --git a/src/php/views/welcome.php b/src/php/views/welcome.php index 05316134..e72014e0 100644 --- a/src/php/views/welcome.php +++ b/src/php/views/welcome.php @@ -18,9 +18,9 @@ return; } -$hero = $this->api->get_hero_item(); +$code_snippets_hero = $this->api->get_hero_item(); -$changelog_sections = [ +$code_snippets_changelog_sections = [ 'Added' => [ 'title' => __( 'New features', 'code-snippets' ), 'icon' => 'lightbulb', @@ -39,7 +39,7 @@ ], ]; -$plugin_types = [ +$code_snippets_plugin_types = [ 'core' => __( 'Core', 'code-snippets' ), 'pro' => __( 'Pro', 'code-snippets' ), ]; @@ -78,50 +78,50 @@ class="csp-link-">
-
-

📰

-
- -
- -

-
-
-
- <?php esc_attr_e( 'Latest news image', 'code-snippets' ); ?>); -
-
+
+

📰

+
+ +
+ +

+
+
+
+ <?php esc_attr_e( 'Latest news image', 'code-snippets' ); ?>); +
+
-
- -

-
-
- api->get_changelog() as $version => $version_changes ) { ?> -

-
- $section ) { - if ( empty( $version_changes[ $section_key ] ) ) { - continue; - } - ?> -

- - -

-
    - $type_label ) { - if ( empty( $version_changes[ $section_key ][ $plugin_type ] ) ) { - continue; - } +
    + +

    +
    +
    + api->get_changelog() as $version => $version_changes ) { ?> +

    +
    + $section ) { + if ( empty( $version_changes[ $section_key ] ) ) { + continue; + } + ?> +

    + + +

    +
      + $type_label ) { + if ( empty( $version_changes[ $section_key ][ $plugin_type ] ) ) { + continue; + } foreach ( $version_changes[ $section_key ][ $plugin_type ] as $change ) { ?> From aaa64c252430b370462b2f635d4a9b4ff2cd16a7 Mon Sep 17 00:00:00 2001 From: Imants Date: Fri, 12 Dec 2025 01:39:36 +0200 Subject: [PATCH 07/10] fix: improve styling for date columns in snippets table --- src/css/manage.scss | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/css/manage.scss b/src/css/manage.scss index f3a4a373..f232bb4d 100644 --- a/src/css/manage.scss +++ b/src/css/manage.scss @@ -137,6 +137,15 @@ #wpbody-content & .column-name { white-space: nowrap; /* prevents wrapping of snippet title */ } + + td.column-date, th.column-date { + white-space: nowrap; + min-inline-size: 110px; + max-inline-size: 200px; + text-align: right; + padding-inline-start: 8px; + padding-inline-end: 8px; + } } td.column-description { From 042e638f75e4747b31de60b0c7b2a50ae181a0be Mon Sep 17 00:00:00 2001 From: Imants Date: Fri, 12 Dec 2025 02:34:39 +0200 Subject: [PATCH 08/10] chore: add screenshot for local tests --- .../snippet-row-active-darwin.png | Bin 0 -> 8772 bytes .../snippet-row-inactive-darwin.png | Bin 0 -> 8686 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/e2e/code-snippets-list.spec.ts-snapshots/snippet-row-active-darwin.png create mode 100644 tests/e2e/code-snippets-list.spec.ts-snapshots/snippet-row-inactive-darwin.png diff --git a/tests/e2e/code-snippets-list.spec.ts-snapshots/snippet-row-active-darwin.png b/tests/e2e/code-snippets-list.spec.ts-snapshots/snippet-row-active-darwin.png new file mode 100644 index 0000000000000000000000000000000000000000..ac04337d6deb3045adafb7557906fc62b510f2dd GIT binary patch literal 8772 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 Vs0Rfm0j%ehl$e}o1;8NSe*o(k8-M@+ literal 0 HcmV?d00001 diff --git a/tests/e2e/code-snippets-list.spec.ts-snapshots/snippet-row-inactive-darwin.png b/tests/e2e/code-snippets-list.spec.ts-snapshots/snippet-row-inactive-darwin.png new file mode 100644 index 0000000000000000000000000000000000000000..18de391bea8fd76c58a881e67781aa062bd4a2c2 GIT binary patch literal 8686 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 h@waI3 Date: Fri, 12 Dec 2025 02:34:59 +0200 Subject: [PATCH 09/10] fix: authentication setup to handle WordPress DB upgrade --- tests/e2e/auth.setup.ts | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/tests/e2e/auth.setup.ts b/tests/e2e/auth.setup.ts index 59a5c39c..63d56d1b 100644 --- a/tests/e2e/auth.setup.ts +++ b/tests/e2e/auth.setup.ts @@ -12,8 +12,25 @@ setup('authenticate', async ({ page }) => { await page.click('#wp-submit') - await page.waitForURL(/wp-admin/) - await page.waitForSelector('#wpbody-content, #adminmenu') + // If WordPress shows the DB upgrade interstitial it includes a link to + // `upgrade.php`. In that case navigate back to `/wp-admin` (the upgrade + // process is handled by the environment) and then wait for the admin UI. + const upgradeLink = page.locator('a[href*="upgrade.php"]') + if (0 < await upgradeLink.count()) { + // Click the upgrade link to reach the upgrade interstitial page. + await upgradeLink.first().click() + + // If the interstitial shows an "Update WordPress Database" action, click it. + const updateBtn = page.locator('a:has-text("Update WordPress Database")') + if (0 < await updateBtn.count()) { + await updateBtn.first().click() + } + // Give the upgrade process more time to complete and the admin UI to load. + await page.waitForSelector('#wpbody-content, #adminmenu', { timeout: 120000 }) + } else { + // Normal path: wait for admin UI. + await page.waitForSelector('#wpbody-content, #adminmenu', { timeout: 60000 }) + } await expect(page.locator('#adminmenu')).toBeVisible() From 1ed23bb1049f87d7cf9cfb1e699481ecdcb37b77 Mon Sep 17 00:00:00 2001 From: Imants Date: Fri, 12 Dec 2025 02:35:04 +0200 Subject: [PATCH 10/10] fix: adjust column widths and overflow handling for date and name columns --- src/css/manage.scss | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/css/manage.scss b/src/css/manage.scss index f232bb4d..173c5596 100644 --- a/src/css/manage.scss +++ b/src/css/manage.scss @@ -140,11 +140,22 @@ td.column-date, th.column-date { white-space: nowrap; - min-inline-size: 110px; - max-inline-size: 200px; + inline-size: 130px; /* fixed column width */ + min-inline-size: 130px; + max-inline-size: 130px; text-align: right; padding-inline-start: 8px; padding-inline-end: 8px; + overflow: hidden; + text-overflow: ellipsis; + } + + /* Ensure the name column can shrink/ellipsis instead of pushing the date. */ + td.column-name, th.column-name { + max-inline-size: calc(100% - 140px); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } }