' . esc_html__( 'Missing', 'ariaccess' ) . '';
} else {
echo esc_html( mb_strlen( $alt ) > 60 ? mb_substr( $alt, 0, 59 ) . '…' : $alt );
}
}
/**
* Image MIME types query value.
*
* @return string
*/
private static function image_mimes() {
return 'image';
}
/**
* Count images without alt text.
*
* @return int
*/
public static function missing_count() {
$q = new WP_Query( self::missing_args( array( 'posts_per_page' => 1, 'fields' => 'ids' ) ) );
return (int) $q->found_posts;
}
/**
* Query args for images missing alt text.
*
* @param array $extra Extra args.
* @return array
*/
public static function missing_args( $extra = array() ) {
return array_merge(
array(
'post_type' => 'attachment',
'post_status' => 'inherit',
'post_mime_type' => self::image_mimes(),
'meta_query' => self::missing_meta_query(), // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
'orderby' => 'date',
'order' => 'DESC',
),
$extra
);
}
/**
* Meta query for "no alt text".
*
* @return array
*/
private static function missing_meta_query() {
return array(
'relation' => 'OR',
array(
'key' => '_wp_attachment_image_alt',
'compare' => 'NOT EXISTS',
),
array(
'key' => '_wp_attachment_image_alt',
'value' => '',
),
);
}
/**
* "Missing alt text" view link in the Media Library list.
*
* @param array $views Views.
* @return array
*/
public static function views( $views ) {
$count = self::missing_count();
$url = add_query_arg(
array(
'mode' => 'list',
'ariaccess_alt' => 'missing',
),
admin_url( 'upload.php' )
);
$current = isset( $_GET['ariaccess_alt'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
/* translators: %s: number of images. */
$views['ariaccess_alt'] = sprintf( '%s', esc_url( $url ), $current ? ' class="current" aria-current="page"' : '', sprintf( esc_html__( 'Missing alt text %s', 'ariaccess' ), '(' . number_format_i18n( $count ) . ')' ) );
return $views;
}
/**
* Apply the filter in the Media Library list.
*
* @param WP_Query $q Query.
*/
public static function filter_query( $q ) {
if ( ! $q->is_main_query() || ! isset( $_GET['ariaccess_alt'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
return;
}
global $pagenow;
if ( 'upload.php' !== $pagenow ) {
return;
}
$q->set( 'post_mime_type', self::image_mimes() );
$q->set( 'meta_query', self::missing_meta_query() ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
}
/**
* Save alt text for several images.
*
* @param array $alts id => alt text.
* @return int Number saved.
*/
public static function save_alts( $alts ) {
$saved = 0;
foreach ( (array) $alts as $id => $alt ) {
$id = (int) $id;
$alt = sanitize_text_field( (string) $alt );
if ( ! $id || '' === $alt || ! wp_attachment_is_image( $id ) || ! current_user_can( 'edit_post', $id ) ) {
continue;
}
update_post_meta( $id, '_wp_attachment_image_alt', $alt );
$saved++;
}
return $saved;
}
}