',
__( 'Status', 'amp' ),
__( 'An accepted validation error is one that will not block a URL from being served as AMP; the validation error will be sanitized, normally resulting in the offending markup being stripped from the response to ensure AMP validity.', 'amp' )
)
)
),
AMP_Validation_Error_Taxonomy::FOUND_ELEMENTS_AND_ATTRIBUTES => esc_html__( 'Invalid', 'amp' ),
AMP_Validation_Error_Taxonomy::SOURCES_INVALID_OUTPUT => esc_html__( 'Sources', 'amp' ),
)
);
if ( isset( $columns['title'] ) ) {
$columns['title'] = esc_html__( 'URL', 'amp' );
}
// Move date to end.
if ( isset( $columns['date'] ) ) {
unset( $columns['date'] );
$columns['date'] = esc_html__( 'Last Checked', 'amp' );
}
if ( ! empty( $_GET[ \AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
unset( $columns['error_status'], $columns[ AMP_Validation_Error_Taxonomy::REMOVED_ELEMENTS ], $columns[ AMP_Validation_Error_Taxonomy::REMOVED_ATTRIBUTES ] );
$columns[ AMP_Validation_Error_Taxonomy::SOURCES_INVALID_OUTPUT ] = esc_html__( 'Sources', 'amp' );
$columns['date'] = esc_html__( 'Last Checked', 'amp' );
$columns['title'] = esc_html__( 'URL', 'amp' );
}
return $columns;
}
/**
* Adds post columns to the /wp-admin/post.php page for amp_validated_url.
*
* @return array The filtered post columns.
*/
public static function add_single_post_columns() {
return array(
'cb' => '',
'error' => __( 'Error', 'amp' ),
'status' => sprintf(
'%s',
esc_html__( 'Status', 'amp' ),
esc_attr(
sprintf(
'
%s
%s
',
esc_html__( 'Status', 'amp' ),
esc_html__( 'An accepted validation error is one that will not block a URL from being served as AMP; the validation error will be sanitized, normally resulting in the offending markup being stripped from the response to ensure AMP validity.', 'amp' )
)
)
),
'details' => sprintf(
'%s',
esc_html__( 'Details', 'amp' ),
esc_attr(
sprintf(
'
%s
%s
',
esc_html__( 'Details', 'amp' ),
esc_html__( 'The parent element of where the error occurred.', 'amp' )
)
)
),
'sources_with_invalid_output' => __( 'Sources', 'amp' ),
'error_type' => __( 'Type', 'amp' ),
);
}
/**
* Outputs custom columns in the /wp-admin UI for the AMP validation errors.
*
* @param string $column_name The name of the column.
* @param int $post_id The ID of the post for the column.
* @return void
*/
public static function output_custom_column( $column_name, $post_id ) {
$post = get_post( $post_id );
if ( self::POST_TYPE_SLUG !== $post->post_type ) {
return;
}
$validation_errors = self::get_invalid_url_validation_errors( $post_id );
$error_summary = AMP_Validation_Error_Taxonomy::summarize_validation_errors( wp_list_pluck( $validation_errors, 'data' ) );
switch ( $column_name ) {
case 'error_status':
$staleness = self::get_post_staleness( $post_id );
if ( ! empty( $staleness ) ) {
echo '' . esc_html__( 'Stale results', 'amp' ) . ' ';
}
self::display_invalid_url_validation_error_counts_summary( $post_id );
break;
case AMP_Validation_Error_Taxonomy::FOUND_ELEMENTS_AND_ATTRIBUTES:
$items = array();
if ( ! empty( $error_summary[ AMP_Validation_Error_Taxonomy::REMOVED_ELEMENTS ] ) ) {
foreach ( $error_summary[ AMP_Validation_Error_Taxonomy::REMOVED_ELEMENTS ] as $name => $count ) {
if ( 1 === intval( $count ) ) {
$items[] = sprintf( '%s', esc_html( $name ) );
} else {
$items[] = sprintf( '%s (%d)', esc_html( $name ), $count );
}
}
}
if ( ! empty( $error_summary[ AMP_Validation_Error_Taxonomy::REMOVED_ATTRIBUTES ] ) ) {
foreach ( $error_summary[ AMP_Validation_Error_Taxonomy::REMOVED_ATTRIBUTES ] as $name => $count ) {
if ( 1 === intval( $count ) ) {
$items[] = sprintf( '[%s]', esc_html( $name ) );
} else {
$items[] = sprintf( '[%s] (%d)', esc_html( $name ), $count );
}
}
}
if ( ! empty( $items ) ) {
$imploded_items = implode( ',
', $items );
echo sprintf( '
%s
', $imploded_items ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
} else {
esc_html_e( '--', 'amp' );
}
break;
case AMP_Validation_Error_Taxonomy::SOURCES_INVALID_OUTPUT:
self::render_sources_column( $error_summary, $post_id );
break;
}
}
/**
* Renders the sources column on the the single error URL page and the 'AMP Validated URLs' page.
*
* @param array $error_summary The summary of errors.
* @param int $post_id The ID of the amp_validated_url post.
*/
public static function render_sources_column( $error_summary, $post_id ) {
if ( ! isset( $error_summary[ AMP_Validation_Error_Taxonomy::SOURCES_INVALID_OUTPUT ] ) ) {
return;
}
// Show nothing if there are no valudation errors.
if ( 0 === count( array_filter( $error_summary ) ) ) {
esc_html_e( '--', 'amp' );
return;
}
$active_theme = null;
$validated_environment = get_post_meta( $post_id, '_amp_validated_environment', true );
if ( isset( $validated_environment['theme'] ) ) {
$active_theme = $validated_environment['theme'];
}
$sources = $error_summary[ AMP_Validation_Error_Taxonomy::SOURCES_INVALID_OUTPUT ];
$output = array();
$plugins = get_plugins();
foreach ( wp_array_slice_assoc( $sources, array( 'plugin', 'mu-plugin' ) ) as $type => $slugs ) {
$plugin_names = array();
$plugin_slugs = array_unique( $slugs );
foreach ( $plugin_slugs as $plugin_slug ) {
if ( 'mu-plugin' === $type ) {
$plugin_names[] = $plugin_slug;
} else {
$name = $plugin_slug;
foreach ( $plugins as $plugin_file => $plugin_data ) {
if ( strtok( $plugin_file, '/' ) === $plugin_slug ) {
$name = $plugin_data['Name'];
break;
}
}
$plugin_names[] = $name;
}
}
$count = count( $plugin_names );
if ( 1 === $count ) {
$output[] = sprintf( '%s', esc_html( $plugin_names[0] ) );
} else {
$output[] = '';
$output[] = sprintf(
'%s (%d)',
'mu-plugin' === $type ? esc_html__( 'Must-Use Plugins', 'amp' ) : esc_html__( 'Plugins', 'amp' ),
$count
);
$output[] = '
',
esc_attr( $class ),
esc_html(
sprintf(
/* translators: %s is count of validation errors updated */
_n(
'Updated %s validation error.',
'Updated %s validation errors.',
$count,
'amp'
),
number_format_i18n( $count )
)
),
esc_html__( 'Dismiss this notice.', 'amp' )
);
}
if ( 'post' !== get_current_screen()->base ) {
// Display admin notice according to the AMP mode.
if ( amp_is_canonical() ) {
$template_mode = AMP_Theme_Support::STANDARD_MODE_SLUG;
} elseif ( current_theme_supports( AMP_Theme_Support::SLUG ) ) {
$template_mode = AMP_Theme_Support::TRANSITIONAL_MODE_SLUG;
} else {
$template_mode = 'reader';
}
$auto_sanitization = AMP_Options_Manager::get_option( 'auto_accept_sanitization' );
if ( AMP_Theme_Support::STANDARD_MODE_SLUG === $template_mode ) {
$message = __( 'The site is using standard AMP mode, the validation errors found are already automatically handled.', 'amp' );
} elseif ( AMP_Theme_Support::TRANSITIONAL_MODE_SLUG === $template_mode && $auto_sanitization ) {
$message = __( 'The site is using transitional AMP mode with auto-sanitization turned on, the validation errors found are already automatically handled.', 'amp' );
} elseif ( AMP_Theme_Support::TRANSITIONAL_MODE_SLUG === $template_mode ) {
$message = sprintf(
/* translators: %s is a link to the AMP settings screen */
__( 'The site is using transitional AMP mode without auto-sanitization, the validation errors found require action and influence which pages are shown in AMP. For automatically handling the errors turn on auto-sanitization from Validation Handling settings.', 'amp' ),
esc_url( admin_url( 'admin.php?page=' . AMP_Options_Manager::OPTION_NAME ) )
);
} else {
$message = __( 'The site is using AMP reader mode, your theme templates are not used and the errors below are irrelevant.', 'amp' );
}
$class = 'info';
printf(
/* translators: 1. Notice classname; 2. Message text; 3. Screenreader text; */
'
%s
',
esc_attr( $class ),
wp_kses_post( $message )
);
}
/**
* Adds notices to the single error page.
* 1. Notice with detailed error information in an expanding box.
* 2. Notice with accept and reject buttons.
*/
if ( ! empty( $_GET[ \AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG ] ) && isset( $_GET['post_type'] ) && self::POST_TYPE_SLUG === $_GET['post_type'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$error_id = sanitize_key( wp_unslash( $_GET[ \AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$error = AMP_Validation_Error_Taxonomy::get_term( $error_id );
if ( ! $error ) {
return;
}
// @todo Update this to use the method which will be developed in PR #1429 AMP_Validation_Error_Taxonomy::get_term_error() .
$description = json_decode( $error->description, true );
$sanitization = \AMP_Validation_Error_Taxonomy::get_validation_error_sanitization( $description );
$status_text = \AMP_Validation_Error_Taxonomy::get_status_text_with_icon( $sanitization );
$error_code = isset( $description['code'] ) ? $description['code'] : 'error';
$error_title = \AMP_Validation_Error_Taxonomy::get_error_title_from_code( $error_code );
$validation_error = json_decode( $error->description, true );
$accept_all_url = wp_nonce_url(
add_query_arg(
array(
'action' => AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_ACCEPT_ACTION,
'term_id' => $error->term_id,
)
),
AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_ACCEPT_ACTION
);
$reject_all_url = wp_nonce_url(
add_query_arg(
array(
'action' => AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_REJECT_ACTION,
'term_id' => $error->term_id,
)
),
AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_REJECT_ACTION
);
if ( ! $sanitization['forced'] ) {
echo '
';
if ( AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_NEW_ACCEPTED_STATUS === $sanitization['term_status'] || AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_ACK_ACCEPTED_STATUS === $sanitization['term_status'] ) {
if ( amp_is_canonical() ) {
$info = __( 'Rejecting an error means that any URL on which it occurs will not be served as AMP.', 'amp' );
} else {
$info = __( 'Rejecting an error means that any URL on which it occurs will redirect to the non-AMP version.', 'amp' );
}
printf(
'
%s
%s',
esc_html__( 'Reject this validation error for all instances.', 'amp' ) . ' ' . esc_html( $info ),
esc_url( $reject_all_url ),
esc_html__( 'Reject', 'amp' )
);
} elseif ( AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_NEW_REJECTED_STATUS === $sanitization['term_status'] || AMP_Validation_Error_Taxonomy::VALIDATION_ERROR_ACK_REJECTED_STATUS === $sanitization['term_status'] ) {
if ( amp_is_canonical() ) {
$info = __( 'Accepting all validation errors which occur on a URL will allow it to be served as AMP.', 'amp' );
} else {
$info = __( 'Accepting all validation errors which occur on a URL will allow it to be served as AMP.', 'amp' );
}
printf(
'
%s
%s',
esc_html__( 'Accept this error for all instances.', 'amp' ) . ' ' . esc_html( $info ),
esc_url( $accept_all_url ),
esc_html__( 'Accept', 'amp' )
);
} else {
if ( amp_is_canonical() ) {
$info = __( 'Rejecting an error means that any URL on which it occurs will not be served as AMP. If all errors occurring on a URL are accepted, then it will be served as AMP.', 'amp' );
} else {
$info = __( 'Rejecting an error means that any URL on which it occurs will redirect to the non-AMP version. If all errors occurring on a URL are accepted, then it will not redirect.', 'amp' );
}
printf(
'
%s
%s%s',
esc_html__( 'Accept or Reject this error for all instances.', 'amp' ) . ' ' . esc_html( $info ),
esc_url( $reject_all_url ),
esc_html__( 'Reject', 'amp' ),
esc_url( $accept_all_url ),
esc_html__( 'Accept', 'amp' )
);
}
echo '
';
}
?>
%s%s',
esc_html( $error_title ),
esc_html( $description['node_name'] ),
wp_kses_post( $status_text )
);
?>
post_type ) {
throw new Exception( 'invalid_post' );
}
if ( ! current_user_can( 'edit_post', $post->ID ) ) {
throw new Exception( 'unauthorized' );
}
$url = self::get_url_from_post( $post );
} elseif ( isset( $_GET['url'] ) ) {
$url = wp_validate_redirect( esc_url_raw( wp_unslash( $_GET['url'] ) ), null );
if ( ! $url ) {
throw new Exception( 'illegal_url' );
}
// Don't let non-admins create new amp_validated_url posts.
if ( ! current_user_can( 'manage_options' ) ) {
throw new Exception( 'unauthorized' );
}
}
if ( ! $url ) {
throw new Exception( 'missing_url' );
}
$validity = AMP_Validation_Manager::validate_url( $url );
if ( is_wp_error( $validity ) ) {
throw new Exception( esc_html( $validity->get_error_code() ) );
}
$errors = wp_list_pluck( $validity['results'], 'error' );
$stored = self::store_validation_errors(
$errors,
$validity['url'],
array_merge(
array(
'invalid_url_post' => $post,
),
wp_array_slice_assoc( $validity, array( 'queried_object' ) )
)
);
if ( is_wp_error( $stored ) ) {
throw new Exception( esc_html( $stored->get_error_code() ) );
}
$redirect = get_edit_post_link( $stored, 'raw' );
$error_count = count(
array_filter(
$errors,
function ( $error ) {
return ! AMP_Validation_Error_Taxonomy::is_validation_error_sanitized( $error );
}
)
);
$args[ self::URLS_TESTED ] = '1';
$args[ self::REMAINING_ERRORS ] = $error_count;
} catch ( Exception $e ) {
$args['amp_validate_error'] = $e->getMessage();
$args[ self::URLS_TESTED ] = '0';
if ( $post && self::POST_TYPE_SLUG === $post->post_type ) {
$redirect = get_edit_post_link( $post->ID, 'raw' );
} else {
$redirect = admin_url(
add_query_arg(
array( 'post_type' => self::POST_TYPE_SLUG ),
'edit.php'
)
);
}
}
wp_safe_redirect( add_query_arg( $args, $redirect ) );
exit();
}
/**
* Re-check validated URL post for whether it has blocking validation errors.
*
* @param int|WP_Post $post Post.
* @return array|WP_Error List of blocking validation results, or a WP_Error in the case of failure.
*/
public static function recheck_post( $post ) {
if ( ! $post ) {
return new WP_Error( 'missing_post' );
}
$post = get_post( $post );
if ( ! $post ) {
return new WP_Error( 'missing_post' );
}
$url = self::get_url_from_post( $post );
if ( ! $url ) {
return new WP_Error( 'missing_url' );
}
$validity = AMP_Validation_Manager::validate_url( $url );
if ( is_wp_error( $validity ) ) {
return $validity;
}
$validation_errors = wp_list_pluck( $validity['results'], 'error' );
$validation_results = array();
self::store_validation_errors(
$validation_errors,
$validity['url'],
array_merge(
array(
'invalid_url_post' => $post,
),
wp_array_slice_assoc( $validity, array( 'queried_object' ) )
)
);
foreach ( $validation_errors as $error ) {
$sanitized = AMP_Validation_Error_Taxonomy::is_validation_error_sanitized( $error ); // @todo Consider re-using $validity['results'][x]['sanitized'], unless auto-sanitize is causing problem.
$validation_results[] = compact( 'error', 'sanitized' );
}
return $validation_results;
}
/**
* Handle validation error status update.
*
* @see AMP_Validation_Error_Taxonomy::handle_validation_error_update()
* @todo This is duplicated with logic in AMP_Validation_Error_Taxonomy. All of the term updating needs to be refactored to make use of the REST API.
*/
public static function handle_validation_error_status_update() {
check_admin_referer( self::UPDATE_POST_TERM_STATUS_ACTION, self::UPDATE_POST_TERM_STATUS_ACTION . '_nonce' );
if ( empty( $_POST[ AMP_Validation_Manager::VALIDATION_ERROR_TERM_STATUS_QUERY_VAR ] ) || ! is_array( $_POST[ AMP_Validation_Manager::VALIDATION_ERROR_TERM_STATUS_QUERY_VAR ] ) ) {
return;
}
$post = get_post();
if ( ! $post || self::POST_TYPE_SLUG !== $post->post_type ) {
return;
}
if ( ! AMP_Validation_Manager::has_cap() || ! current_user_can( 'edit_post', $post->ID ) ) {
wp_die( esc_html__( 'You do not have permissions to validate an AMP URL. Did you get logged out?', 'amp' ) );
}
$updated_count = 0;
$has_pre_term_description_filter = has_filter( 'pre_term_description', 'wp_filter_kses' );
if ( false !== $has_pre_term_description_filter ) {
remove_filter( 'pre_term_description', 'wp_filter_kses', $has_pre_term_description_filter );
}
foreach ( $_POST[ AMP_Validation_Manager::VALIDATION_ERROR_TERM_STATUS_QUERY_VAR ] as $term_slug => $status ) {
if ( ! is_numeric( $status ) ) {
continue;
}
$term_slug = sanitize_key( $term_slug );
$term = AMP_Validation_Error_Taxonomy::get_term( $term_slug );
if ( ! $term ) {
continue;
}
$term_group = AMP_Validation_Error_Taxonomy::sanitize_term_status( $status );
if ( null !== $term_group && $term_group !== $term->term_group ) {
$updated_count++;
wp_update_term( $term->term_id, AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG, compact( 'term_group' ) );
}
}
if ( false !== $has_pre_term_description_filter ) {
add_filter( 'pre_term_description', 'wp_filter_kses', $has_pre_term_description_filter );
}
$args = array(
'amp_taxonomy_terms_updated' => $updated_count,
);
/*
* Re-check the post after the validation status change. This is particularly important for validation errors like
* 'removed_unused_css_rules' since whether it is accepted will determine whether other validation errors are triggered
* such as in this case 'excessive_css'.
*/
if ( $updated_count > 0 ) {
$validation_results = self::recheck_post( $post->ID );
// @todo For WP_Error case, see .
if ( ! is_wp_error( $validation_results ) ) {
$args[ self::REMAINING_ERRORS ] = count(
array_filter(
$validation_results,
function( $result ) {
return ! $result['sanitized'];
}
)
);
}
}
$redirect = wp_get_referer();
if ( ! $redirect ) {
$redirect = get_edit_post_link( $post->ID, 'raw' );
}
$redirect = remove_query_arg( wp_removable_query_args(), $redirect );
wp_safe_redirect( add_query_arg( $args, $redirect ) );
exit();
}
/**
* Enqueue scripts for the edit post screen.
*/
public static function enqueue_edit_post_screen_scripts() {
$current_screen = get_current_screen();
if ( 'post' !== $current_screen->base || self::POST_TYPE_SLUG !== $current_screen->post_type ) {
return;
}
// Eliminate autosave since it is only relevant for the content editor.
wp_dequeue_script( 'autosave' );
$script_deps_path = AMP__DIR__ . '/assets/js/' . self::EDIT_POST_SCRIPT_HANDLE . '.deps.json';
$script_dependencies = file_exists( $script_deps_path )
? json_decode( file_get_contents( $script_deps_path ), false ) // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
: array();
wp_enqueue_script(
self::EDIT_POST_SCRIPT_HANDLE,
amp_get_asset_url( 'js/' . self::EDIT_POST_SCRIPT_HANDLE . '.js' ),
$script_dependencies,
AMP__VERSION,
true
);
$current_screen = get_current_screen();
if ( $current_screen && 'post' === $current_screen->base && self::POST_TYPE_SLUG === $current_screen->post_type ) {
$post = get_post();
$data = array(
'page_heading' => self::get_single_url_page_heading(),
'amp_enabled' => self::is_amp_enabled_on_post( $post ),
);
wp_localize_script(
self::EDIT_POST_SCRIPT_HANDLE,
'ampValidation',
$data
);
}
if ( function_exists( 'wp_set_script_translations' ) ) {
wp_set_script_translations( self::EDIT_POST_SCRIPT_HANDLE, 'amp' );
} elseif ( function_exists( 'wp_get_jed_locale_data' ) || function_exists( 'gutenberg_get_jed_locale_data' ) ) {
$locale_data = function_exists( 'wp_get_jed_locale_data' ) ? wp_get_jed_locale_data( 'amp' ) : gutenberg_get_jed_locale_data( 'amp' );
$translations = wp_json_encode( $locale_data );
wp_add_inline_script(
self::EDIT_POST_SCRIPT_HANDLE,
'wp.i18n.setLocaleData( ' . $translations . ', "amp" );',
'after'
);
}
}
/**
* Adds the meta boxes to the CPT post.php page.
*
* @return void
*/
public static function add_meta_boxes() {
remove_meta_box( 'submitdiv', self::POST_TYPE_SLUG, 'side' );
remove_meta_box( 'slugdiv', self::POST_TYPE_SLUG, 'normal' );
add_meta_box(
self::STATUS_META_BOX,
__( 'Status', 'amp' ),
array( __CLASS__, 'print_status_meta_box' ),
self::POST_TYPE_SLUG,
'side',
'default',
array( '__back_compat_meta_box' => true )
);
}
/**
* Outputs the markup of the side meta box in the CPT post.php page.
*
* This is partially copied from meta-boxes.php.
* Adds 'Published on,' and links to move to trash and recheck.
*
* @param WP_Post $post The post for which to output the box.
* @return void
*/
public static function print_status_meta_box( $post ) {
?>
%s', 'amp' ) ),
/* translators: Meta box date format */
esc_html( date_i18n( __( 'M j, Y @ H:i', 'amp' ), strtotime( $post->post_date ) ) )
);
?>
';
echo '';
esc_html_e( 'Stale results', 'amp' );
echo '';
echo ' ';
if ( ! empty( $staleness['theme'] ) && ! empty( $staleness['plugins'] ) ) {
esc_html_e( 'Different theme and plugins were active when these results were obtained.', 'amp' );
echo ' ';
} elseif ( ! empty( $staleness['theme'] ) ) {
esc_html_e( 'A different theme was active when these results were obtained.', 'amp' );
echo ' ';
} elseif ( ! empty( $staleness['plugins'] ) ) {
esc_html_e( 'Different plugins were active when these results were obtained.', 'amp' );
echo ' ';
}
esc_html_e( 'Please recheck.', 'amp' );
echo '
post_type ) {
return;
}
$taxonomy = AMP_Validation_Error_Taxonomy::TAXONOMY_SLUG;
$taxonomy_object = get_taxonomy( $taxonomy );
if ( ! $taxonomy_object ) {
wp_die( esc_html__( 'Invalid taxonomy.', 'amp' ) );
}
/**
* Set the order of the terms in the order of occurrence.
*
* Note that this function will call \AMP_Validation_Error_Taxonomy::get_term() repeatedly, and the
* object cache will be pre-populated with terms due to the term query in the term list table.
*
* @return WP_Term[]
*/
$override_terms_in_occurrence_order = function() use ( $post ) {
return wp_list_pluck( AMP_Validated_URL_Post_Type::get_invalid_url_validation_errors( $post ), 'term' );
};
add_filter( 'get_terms', $override_terms_in_occurrence_order );
$wp_list_table = _get_list_table( 'WP_Terms_List_Table' );
get_current_screen()->set_screen_reader_content(
array(
'heading_pagination' => $taxonomy_object->labels->items_list_navigation,
'heading_list' => $taxonomy_object->labels->items_list,
)
);
$wp_list_table->prepare_items();
$wp_list_table->views();
// The inline script depends on data from the list table.
self::$total_errors_for_url = $wp_list_table->get_pagination_arg( 'total_items' );
?>