> */ public static function search( $q = '', $limit = self::DEFAULT_RESULTS, $mime = 'image' ) { $limit = max( 1, min( self::MAX_RESULTS, (int) $limit ) ); $q = trim( (string) $q ); $mime = sanitize_text_field( (string) $mime ); $base = array( 'post_type' => 'attachment', 'post_status' => 'inherit', 'posts_per_page' => $limit, 'orderby' => 'date', 'order' => 'DESC', 'no_found_rows' => true, 'fields' => 'ids', ); if ( '' !== $mime ) { $base['post_mime_type'] = $mime; } $ids = array(); if ( '' === $q ) { $ids = get_posts( $base ); } else { $ids = get_posts( array_merge( $base, array( 's' => $q ) ) ); // Only pay for the meta scan when the first pass left room. On a // library where the title search already filled the page, the alt // pass could only add rows nobody asked to see. if ( count( $ids ) < $limit ) { $alt = get_posts( array_merge( $base, array( 'posts_per_page' => $limit - count( $ids ), 'post__not_in' => $ids, 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query -- The only place alt text lives; bounded by posts_per_page. array( 'key' => '_wp_attachment_image_alt', 'value' => $q, 'compare' => 'LIKE', ), ), ) ) ); $ids = array_merge( $ids, $alt ); } } $out = array(); foreach ( $ids as $id ) { $row = self::row( (int) $id ); if ( $row ) { $out[] = $row; } } return $out; } /** * One attachment as an agent needs it: enough to choose between pictures, * and the ID to name the one it chose. * * `alt` rides along because it is the only human description most images * carry, and `url` because a multimodal client can look at the picture * rather than guessing from a filename. Dimensions are here for the same * reason a person checks them — a 300px logo is not a featured image. * * @param int $id Attachment ID. * @return array|null Null when the ID isn't a real attachment. */ public static function row( $id ) { $id = (int) $id; $post = $id > 0 ? get_post( $id ) : null; if ( ! $post || 'attachment' !== $post->post_type ) { return null; } $meta = (array) wp_get_attachment_metadata( $id ); return array( 'id' => $id, 'title' => html_entity_decode( (string) get_the_title( $id ), ENT_QUOTES, 'UTF-8' ), 'alt' => (string) get_post_meta( $id, '_wp_attachment_image_alt', true ), 'url' => (string) wp_get_attachment_url( $id ), 'mime' => (string) get_post_mime_type( $id ), 'width' => (int) ( isset( $meta['width'] ) ? $meta['width'] : 0 ), 'height' => (int) ( isset( $meta['height'] ) ? $meta['height'] : 0 ), 'date' => (string) get_the_date( 'Y-m-d', $post ), ); } }