service_test_id; } /** * Add meta boxes. */ public function add_meta_boxes() { if ( current_user_can( 'manage_options' ) ) { $custom_post_types = get_post_types([ 'public' => true, '_builtin' => false, ]); add_meta_box( 'vrts_post_options_metabox', vrts()->get_plugin_info( 'name' ), [ $this, 'render_metabox' ], array_merge( [ 'post', 'page' ], $custom_post_types ), 'side', 'default', [ '__back_compat_meta_box' => true ] ); } } /** * Add rest actions. */ public function add_rest_actions() { if ( current_user_can( 'manage_options' ) ) { $custom_post_types = get_post_types([ 'public' => true, '_builtin' => false, ]); foreach ( array_merge( [ 'post', 'page' ], $custom_post_types ) as $custom_post_type ) { add_action( 'rest_after_insert_' . $custom_post_type, [ $this, 'update_rest_data' ], 10, 2 ); } } } /** * Render meta box. */ public function render_metabox() { global $post; $post_id = $post->ID ? $post->ID : 0; $test_id = Test::get_item_id( $post_id ); $test = (object) Test::get_item( $test_id ); $run_tests_checked = ! is_null( $test_id ); $alert_id = $test->current_alert_id ?? null; $testing_status_instructions = ''; if ( $alert_id ) { $alert_link = Url_Helpers::get_alert_page( $alert_id ); $testing_status_instructions .= sprintf( /* translators: %1$s and %2$s: link wrapper. */ esc_html__( '%1$sView Alert%2$s', 'visual-regression-tests' ), '', '' ); } vrts()->component('metabox-classic-editor', [ 'post_id' => $post_id, 'nonce' => $this->nonce, 'plugin_url' => Url_Helpers::get_page_url( 'tests' ), 'run_tests_checked' => $run_tests_checked, 'field_test_status_key' => self::$field_test_status_key, 'has_post_alert' => isset( $test->current_alert_id ) ? ! is_null( $test->current_alert_id ) : false, 'base_screenshot_url' => Image_Helpers::get_screenshot_url( $test, 'base' ), 'base_screenshot_date' => Date_Time_Helpers::get_formatted_date_time( $test->base_screenshot_date ?? null ), 'testing_status_instructions' => $testing_status_instructions, 'is_new_test' => self::is_new_test( $post_id ), 'remaining_tests' => Subscription::get_remaining_tests(), 'total_tests' => Subscription::get_total_tests(), 'is_connected' => Service::is_connected(), 'test_status' => Test::get_status_data( $test ), 'screenshot' => Test::get_screenshot_data( $test ), 'test_settings' => [ 'test_id' => isset( $test->id ) ? $test->id : null, 'hide_css_selectors' => isset( $test->hide_css_selectors ) ? $test->hide_css_selectors : null, ], ]); } /** * Add meta boxes. * * @param int $post_id Post ID. * @param WP_Post $post Post object. */ public function save_meta_boxes_data( $post_id, $post ) { $edit_cap = get_post_type_object( $post->post_type )->cap->edit_post; if ( ! current_user_can( $edit_cap, $post_id ) ) { return; } $nonce = sanitize_text_field( wp_unslash( $_POST[ $this->nonce ] ?? '' ) ); // Verify nonce. Only valid when using classic editor. if ( ! wp_verify_nonce( $nonce, $this->nonce ) ) { return; } // Save "Run Tests" checkbox value to post meta. if ( array_key_exists( self::$field_test_status_key, $_POST ) && '1' === $_POST[ self::$field_test_status_key ] ) { $service = new Test_Service(); $service->create_test( $post_id ); } else { // Delete data from tests database table if "Run Tests" checkbox is not checked. $test_id = Test::get_item_id( $post_id ); if ( $test_id ) { $service = new Test_Service(); $service->delete_test( (int) $test_id ); } } // Save Settings of the test. $test = (object) Test::get_item_by_post_id( $post_id ); $test_id = isset( $_POST['test_id'] ) ? (int) sanitize_text_field( wp_unslash( $_POST['test_id'] ) ) : 0; if ( ! empty( $test ) && ! empty( $test->id ) && (int) $test->id === (int) $test_id ) { $hide_css_selectors = isset( $_POST['hide_css_selectors'] ) ? sanitize_text_field( wp_unslash( $_POST['hide_css_selectors'] ) ) : ''; $test_service = new Test_Service(); $test_service->update_css_hide_selectors( $test_id, $hide_css_selectors ); } } /** * Delete post meta keys. */ public static function delete_meta_keys() { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- It's ok. $wpdb->delete( $wpdb->postmeta, [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- TODO: Check later 'meta_key' => self::get_post_meta_key_status(), ] ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- It's ok. $wpdb->delete( $wpdb->postmeta, [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- TODO: Check later 'meta_key' => self::get_post_meta_key_is_new_test(), ] ); } /** * Update rest data. * * @param WP_Post $post Post object. * @param WP_REST_Request $request Request object. */ public function update_rest_data( $post, $request ) { $vrts_params = $request->get_param( 'vrts' ); if ( array_key_exists( 'hide_css_selectors', $vrts_params ?? [] ) ) { $hide_css_selectors = $vrts_params['hide_css_selectors'] ? sanitize_text_field( $vrts_params['hide_css_selectors'] ) : ''; $test_id = Test::get_item_id( $post->ID ); $test_service = new Test_Service(); $test_service->update_css_hide_selectors( $test_id, $hide_css_selectors ); } } }