'test', 'plural' => 'tests', 'ajax' => false, ]); } /** * Get table classes. */ public function get_table_classes() { return [ 'widefat', 'fixed', $this->_args['plural'] ]; } /** * Message to show if no designation found. * * @return void */ public function no_items() { esc_attr_e( 'No tests found.', 'visual-regression-tests' ); } /** * Default column values if no callback found. * * @param object $item comment column item. * @param string $column_name column name. * * @return string */ public function column_default( $item, $column_name ) { switch ( $column_name ) { case 'post_title': return $item->post_title; case 'internal_url': $parsed_internal_url = wp_parse_url( get_permalink( $item->post_id ) ); $internal_url = $parsed_internal_url['path']; return sprintf( '%3$s', get_post_permalink( $item->post_id ), esc_html__( 'Open the page in a new tab', 'visual-regression-tests' ), $internal_url ); case 'status': return $this->render_column_status( $item ); case 'base_screenshot_date': return $this->render_column_snapshot( $item ); default: return isset( $item->$column_name ) ? $item->$column_name : ''; }//end switch } /** * Get the column names. * * @return array */ public function get_columns() { $columns = [ 'cb' => '', 'post_title' => esc_html__( 'Title', 'visual-regression-tests' ), 'internal_url' => esc_html__( 'Path', 'visual-regression-tests' ), 'base_screenshot_date' => esc_html__( 'Snapshot', 'visual-regression-tests' ), 'status' => esc_html__( 'Test Status', 'visual-regression-tests' ), ]; return $columns; } /** * Render the designation name column. * * @param object $item column item. * * @return string */ public function column_post_title( $item ) { $actions = []; $is_connected = Service::is_connected(); $actions['edit'] = sprintf( '%s', get_edit_post_link( $item->post_id ), $item->id, esc_html__( 'Edit this page', 'visual-regression-tests' ), esc_html__( 'Edit Page', 'visual-regression-tests' ) ); $actions['inline hide-if-no-js'] = sprintf( '', /* translators: %s: Page Title. */ esc_attr( sprintf( __( 'Quick edit “%s” inline', 'visual-regression-tests' ), $item->post_title ) ), __( 'Quick Edit', 'visual-regression-tests' ) ); if ( $is_connected ) { $actions['trash'] = sprintf( '%s', Url_Helpers::get_disable_testing_url( $item->id ), $item->id, esc_html__( 'Disable testing for this page', 'visual-regression-tests' ), esc_html__( 'Disable Testing', 'visual-regression-tests' ) ); } $row_actions = sprintf( '%3$s %4$s', get_edit_post_link( $item->post_id ), esc_html__( 'Edit this page', 'visual-regression-tests' ), $item->post_title, $this->row_actions( $actions ) ); $quickedit_hidden_fields = " "; return $row_actions . $quickedit_hidden_fields; } /** * Get sortable columns * * @return array */ public function get_sortable_columns() { $sortable_columns = [ 'post_title' => [ 'post_title', true ], 'status' => [ 'status', true ], 'base_screenshot_date' => [ 'base_screenshot_date', true ], ]; return $sortable_columns; } /** * Set the bulk actions * * @return array */ public function get_bulk_actions() { $actions = [ 'set-status-disable' => esc_html__( 'Disable Testing', 'visual-regression-tests' ), ]; if ( Subscription::get_subscription_status() && count( Test::get_all_running() ) > 0 ) { $actions = array_merge( [ 'run-manual-test' => esc_html__( 'Run Test', 'visual-regression-tests' ) ], $actions ); } return $actions; } /** * Process bulk actions. * * @return void */ public function process_bulk_action() { // verify the nonce. $nonce = sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ?? '' ) ); if ( ! wp_verify_nonce( $nonce, 'bulk-' . $this->_args['plural'] ) ) { return; } // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Should be okay for now. $test_ids = wp_unslash( $_POST['id'] ?? 0 ); if ( 0 === $test_ids ) { return; } if ( 'set-status-disable' === $this->current_action() ) { foreach ( $test_ids as $test_id ) { $item = Test::get_item( $test_id ); if ( $item ) { $service = new Test_Service(); $service->delete_test( (int) $item->id ); } } } } /** * Render the checkbox column * * @param object $item column item. * * @return string */ public function column_cb( $item ) { return sprintf( '', $item->id ); } /** * Gets the list of views available on this table. * * @return array */ public function get_views() { $base_link = Url_Helpers::get_page_url( 'tests' ); $links = [ 'all' => [ 'title' => esc_html__( 'All', 'visual-regression-tests' ), 'link' => $base_link, 'count' => Test::get_total_items(), ], 'changes-detected' => [ 'title' => esc_html__( 'Changes detected', 'visual-regression-tests' ), 'link' => "{$base_link}&status=changes-detected", 'count' => Test::get_total_items( 'changes-detected' ), ], ]; $status_links = []; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- It's status request. $filter_status_query = ( isset( $_REQUEST['status'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['status'] ) ) : 'all' ); foreach ( $links as $key => $link ) { $current_class = ( $filter_status_query === $key ? 'class="current" ' : '' ); $link = sprintf( '%s (%s)', $current_class, $link['link'], $link['title'], $link['count'] ); $status_links[ $key ] = $link; } return $status_links; } /** * Add extra markup in the toolbars before or after the list. * * @param string $which helps you decide if you add the markup after (bottom) or before (top) the list. */ public function extra_tablenav( $which ) { } /** * Prepare the class items * * @return void */ public function prepare_items() { $columns = $this->get_columns(); $hidden = []; $sortable = $this->get_sortable_columns(); $this->_column_headers = [ $columns, $hidden, $sortable ]; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- It's the list order parameter. $order = isset( $_REQUEST['order'] ) && 'asc' === $_REQUEST['order'] ? 'ASC' : 'DESC'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- It's the list order by parameter. $order_by = isset( $_REQUEST['orderby'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ) : 'id'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing -- It's the list search query parameter. $search_query = isset( $_POST['s'] ) && '' !== $_POST['s'] ? sanitize_text_field( wp_unslash( $_POST['s'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing -- It's the list search query parameter. $filter_status_query = isset( $_REQUEST['status'] ) && '' !== $_REQUEST['status'] ? sanitize_text_field( wp_unslash( $_REQUEST['status'] ) ) : null; $args = [ 'number' => -1, 'order' => $order, 'orderby' => $order_by, 's' => $search_query, 'filter_status' => $filter_status_query, ]; // Process any bulk actions. $this->process_bulk_action(); $this->items = Test::get_items( $args ); $total_items = count( $this->items ); $this->set_pagination_args([ 'total_items' => $total_items, // we set it to a high number to avoid pagination. 'per_page' => 100000, ]); } /** * Generates content for a single row of the table. * * @param object|array $item The current item. */ public function single_row( $item ) { $classes = 'iedit'; ?> single_row_columns( $item ); ?> screen; ?>
post_type}"; $classes = $inline_edit_classes . ' ' . $quick_edit_classes; ?>

%s

%s

', 'vrts-testing-status--' . $status_data['class'], $status_data['text'], $status_data['instructions'] ); } /** * Render the snapshot column. * * @param object $item column item. * * @return string */ private function render_column_snapshot( $item ) { $screenshot_data = Test::get_screenshot_data( $item ); return sprintf( '

%s

%s

', $screenshot_data['text'], $screenshot_data['instructions'] ); } }