prepare_items(); // Begin UI rendering. $table_type = property_exists( $list_table, 'item_type' ) ? (string) $list_table->item_type : 'item'; self::render_form_start( $table_type ); self::render_optimization_settings_form( $user_credits, $list_table ); $persistent_inputs = self::get_persistent_query_args(); self::render_hidden_inputs( array_merge( $persistent_inputs, $hidden_inputs ) ); self::render_table_section( $list_table, $search_label ); self::render_form_end(); } /** * Render the optimization settings form. * * @param int $user_credits Credits available to the current user. * @param object $list_table Must support get_meta_field_options(): array {string: array}. * @return void */ private static function render_optimization_settings_form( $user_credits, $list_table ): void { self::render_credits_and_submit_section( $user_credits ); self::render_field_checkboxes_section( $list_table ); } /** * Attempt to instantiate the requested list table class. * * @param string $list_table_class Fully-qualified class name. * @return object|null Instance of the class, or null if invalid. */ private static function instantiate_list_table( string $list_table_class ): ?object { if ( ! class_exists( $list_table_class ) ) { return null; } $instance = new $list_table_class(); return $instance; } /** * Render an admin notice for invalid list table class. * * @param string $list_table_class Fully-qualified class name. * @return void */ private static function render_invalid_class_notice( string $list_table_class ): void { echo '

'; echo esc_html( Messages::get( 'optimize.invalid_class' ) ) . esc_html( $list_table_class ); echo '

'; } /** * Output the opening
. * * @param string $table_type Table identifier type. * @return void */ private static function render_form_start( string $table_type ): void { echo ''; } /** * Output hidden inputs. * * @param array $hidden_inputs Key/value map of hidden inputs. * @return void */ private static function render_hidden_inputs( array $hidden_inputs ): void { foreach ( $hidden_inputs as $name => $value ) { printf( '', esc_attr( (string) $name ), esc_attr( (string) $value ) ); } } /** * Retrieve the current request query vars that must persist across form submissions. * * Ensures pagination/search submissions preserve the admin screen context (page, tab, etc). * * @return array */ private static function get_persistent_query_args(): array { $keys_to_preserve = array( 'page', 'tab', 'post_type', 'section' ); $values = array(); foreach ( $keys_to_preserve as $key ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only filter parameter. if ( isset( $_GET[ $key ] ) && is_string( $_GET[ $key ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- unslashed + sanitized below. $raw = wp_unslash( $_GET[ $key ] ); $values[ $key ] = sanitize_text_field( $raw ); } } return $values; } /** * Render the search box, table title, and table itself. * * @param object $list_table Must support search_box(), display_title(), and display(). * @param string $search_label Label for the search box. * @return void */ private static function render_table_section( object $list_table, string $search_label ): void { // The original uses a constant ID of 'search_id'; keep as-is to avoid behavior changes. if ( method_exists( $list_table, 'search_box' ) ) { $list_table->search_box( $search_label, 'search_id' ); } if ( method_exists( $list_table, 'display_title' ) ) { $list_table->display_title(); } if ( method_exists( $list_table, 'display' ) ) { $list_table->display(); } } /** * Render the "Select Fields to Optimize" checkbox section. * * @param object $list_table Must support get_meta_field_options(): array {string: array}. * @return void */ private static function render_field_checkboxes_section( object $list_table ): void { echo '

' . esc_html( Messages::get( 'optimize.select_fields' ) ) . '

'; if ( method_exists( $list_table, 'get_meta_field_options' ) ) { $options = (array) $list_table->get_meta_field_options(); foreach ( $options as $id => $data ) { // Preserve original naming/data-ref/value behavior exactly. $input_id = (string) $id; $input_name = (string) $id; $value = isset( $data[0] ) ? (string) $data[0] : ''; $label = isset( $data[1] ) ? (string) $data[1] : ''; echo '

'; printf( '', esc_attr( $input_id ), esc_attr( $input_name ), esc_attr( $value ) ); printf( '', esc_attr( $input_id ), esc_html( $label ) ); echo '

'; } } echo '
'; } /** * Render credits summary, hidden total_credits_required input, and submit button. * * @param int $user_credits Credits available to the current user. * @return void */ private static function render_credits_and_submit_section( int $user_credits ): void { echo '
'; printf( '

%s %d

', esc_html( Messages::get( 'optimize.credits_available' ) ), esc_html( $user_credits ) ); echo '

' . esc_html( Messages::get( 'optimize.credits_required' ) ) . ' 0

'; echo ''; $button_attributes = self::build_submit_button_attributes( $user_credits ); echo '

'; submit_button( esc_html( Messages::get( 'optimize.start' ) ), 'primary', 'optimize_products', false, $button_attributes ); echo '

'; } /** * Build the attributes array for submit_button() call. * * @param int $user_credits Credits available to the current user. * @return array */ private static function build_submit_button_attributes( int $user_credits ): array { $attrs = array( 'class' => 'button button-primary', 'data-start-label' => Messages::get( 'optimize.start' ), ); if ( $user_credits < 1 ) { $attrs['disabled'] = 'disabled'; } return $attrs; } /** * Output the closing . * * @return void */ private static function render_form_end(): void { echo ''; } }