How to the get the WordPress Media Search to include tags?

I’ve added tags to all Media items with this code:

function wptp_add_tags_to_attachments() {
    register_taxonomy_for_object_type( 'post_tag', 'attachment' );
}
add_action( 'init' , 'wptp_add_tags_to_attachments' );

It works great expect one thing. If I search for a media file in the Admin Media Library it does not work with tags.

Read More

How can I get the Admin Media Library to include the tags in the search?

Related posts

Leave a Reply

4 comments

  1. You can do this using WordPress action hooks. You need to update the WordPress default search query when searching attachments using hooks posts_where, posts_join and posts_groupby.

    Please add below to your themes functions.php

    function custom_attachments_join( $join, $query )
    {
        global $wpdb;
    
        //if we are not on admin or the current search is not on attachment return
        if(!is_admin() || (!isset($query->query['post_type']) || $query->query['post_type'] != 'attachment')) 
            return $join;
    
        //  if current query is the main query and a search...
        if( is_main_query() && is_search() )
        {
            $join .= "
            LEFT JOIN
            {$wpdb->term_relationships} ON {$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id
            LEFT JOIN
            {$wpdb->term_taxonomy} ON {$wpdb->term_taxonomy}.term_taxonomy_id = {$wpdb->term_relationships}.term_taxonomy_id
            LEFT JOIN
            {$wpdb->terms} ON {$wpdb->terms}.term_id = {$wpdb->term_taxonomy}.term_id ";
        }
    
        return $join;
    }
    add_filter( 'posts_join', 'custom_attachments_join', 10, 2 );
    
    function custom_attachments_where( $where, $query )
    {
        global $wpdb;
    
        //if we are not on admin or the current search is not on attachment return
        if(!is_admin() || (!isset($query->query['post_type']) || $query->query['post_type'] != 'attachment'))
            return $where;
    
        //  if current query is the main query and a search...
        if( is_main_query() && is_search() )
        {
            //  explictly search post_tag taxonomies
            $where .= " OR ( 
                            ( {$wpdb->term_taxonomy}.taxonomy IN('post_tag') AND {$wpdb->terms}.name LIKE '%" . $wpdb->escape( get_query_var('s') ) . "%' )
                           )";
    
        }
    
        return $where;
    }
    add_filter( 'posts_where', 'custom_attachments_where', 10, 2 );
    
    function custom_attachments_groupby( $groupby, $query )
    {
    
        global $wpdb;
    
        //if we are not on admin or the current search is not on attachment return
        if(!is_admin() || (!isset($query->query['post_type']) || $query->query['post_type'] != 'attachment'))
            return $groupby;
    
        //  if current query is the main query and a search...
        if( is_main_query() && is_search() )
        {
            //  assign the GROUPBY
            $groupby = "{$wpdb->posts}.ID";
        }
    
        return $groupby;
    
    }
    add_filter( 'posts_groupby', 'custom_attachments_groupby', 10, 2 );
    

    What these functions does is:

    1. custom_attachments_join functions joins term_relationships and term_taxonomy for giving us ability to search for tags
    2. custom_attachments_where function modifies the WordPress default where condition to include our search terms to search for taxonomy or terms fields
    3. custom_attachments_groupby adds group by condition to remove duplicate posts if any.

    These functions also check whether we are searching for attachment and if we are performing the search in the WordPress admin area.

    Please check with this links for more reference on the hooks I have used.

    Hope this helps you

  2. Unfortunately Sabari’s solution doesn’t work for the search-form in the “Add Media” – section.

    I am using the following function in my functions.php (code based on the “Media Search Enhanced” plugin by Yoren Chang):

    function myprefix_posts_clauses( $pieces ) {
    
      global $wp_query, $wpdb;
    
      $vars = $wp_query->query_vars;
      if ( empty( $vars ) ) {
        $vars = ( isset( $_REQUEST['query'] ) ) ? $_REQUEST['query'] : array();
      }
    
      // Rewrite the where clause
      if ( ! empty( $vars['s'] ) && ( ( isset( $_REQUEST['action'] ) && 'query-attachments' == $_REQUEST['action'] ) || 'attachment' == $vars['post_type'] ) ) {
        $pieces['where'] = " AND $wpdb->posts.post_type = 'attachment' AND ($wpdb->posts.post_status = 'inherit' OR $wpdb->posts.post_status = 'private')";
    
        if ( class_exists('WPML_Media') ) {
          global $sitepress;
          //get current language
          $lang = $sitepress->get_current_language();
          $pieces['where'] .= $wpdb->prepare( " AND wpml_translations.element_type='post_attachment' AND wpml_translations.language_code = %s", $lang );
        }
    
        if ( ! empty( $vars['post_parent'] ) ) {
          $pieces['where'] .= " AND $wpdb->posts.post_parent = " . $vars['post_parent'];
        } elseif ( 0 === $vars['post_parent'] ) {
          // Get unattached attachments
          $pieces['where'] .= " AND $wpdb->posts.post_parent = 0";
        }
    
        if ( ! empty( $vars['post_mime_type'] ) ) {
          // Use esc_like to escape slash
          $like = '%' . $wpdb->esc_like( $vars['post_mime_type'] ) . '%';
          $pieces['where'] .= $wpdb->prepare( " AND $wpdb->posts.post_mime_type LIKE %s", $like );
        }
    
        if ( ! empty( $vars['m'] ) ) {
          $year = substr( $vars['m'], 0, 4 );
          $monthnum = substr( $vars['m'], 4 );
          $pieces['where'] .= $wpdb->prepare( " AND YEAR($wpdb->posts.post_date) = %d AND MONTH($wpdb->posts.post_date) = %d", $year, $monthnum );
        } else {
          if ( ! empty( $vars['year'] ) && 'false' != $vars['year'] ) {
            $pieces['where'] .= $wpdb->prepare( " AND YEAR($wpdb->posts.post_date) = %d", $vars['year'] );
          }
    
          if ( ! empty( $vars['monthnum'] ) && 'false' != $vars['monthnum'] ) {
            $pieces['where'] .= $wpdb->prepare( " AND MONTH($wpdb->posts.post_date) = %d", $vars['monthnum'] );
          }
        }
    
        // search for keyword "s"
        $like = '%' . $wpdb->esc_like( $vars['s'] ) . '%';
        $pieces['where'] .= $wpdb->prepare( " AND ( ($wpdb->posts.ID LIKE %s) OR ($wpdb->posts.post_title LIKE %s) OR ($wpdb->posts.guid LIKE %s) OR ($wpdb->posts.post_content LIKE %s) OR ($wpdb->posts.post_excerpt LIKE %s)", $like, $like, $like, $like, $like );
        $pieces['where'] .= $wpdb->prepare( " OR ($wpdb->postmeta.meta_key = '_wp_attachment_image_alt' AND $wpdb->postmeta.meta_value LIKE %s)", $like );
        $pieces['where'] .= $wpdb->prepare( " OR ($wpdb->postmeta.meta_key = '_wp_attached_file' AND $wpdb->postmeta.meta_value LIKE %s)", $like );
    
        // Get taxes for attachements
        $taxes = get_object_taxonomies( 'attachment' );
        if ( ! empty( $taxes ) ) {
          $pieces['where'] .= $wpdb->prepare( " OR (tter.slug LIKE %s) OR (ttax.description LIKE %s) OR (tter.name LIKE %s)", $like, $like, $like );
        }
    
        $pieces['where'] .= " )";
    
        $pieces['join'] .= " LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id";
    
        // Get taxes for attachements
        $taxes = get_object_taxonomies( 'attachment' );
        if ( ! empty( $taxes ) ) {
          $on = array();
          foreach ( $taxes as $tax ) {
            $on[] = "ttax.taxonomy = '$tax'";
          }
          $on = '( ' . implode( ' OR ', $on ) . ' )';
    
          $pieces['join'] .= " LEFT JOIN $wpdb->term_relationships AS trel ON ($wpdb->posts.ID = trel.object_id) LEFT JOIN $wpdb->term_taxonomy AS ttax ON (" . $on . " AND trel.term_taxonomy_id = ttax.term_taxonomy_id) LEFT JOIN $wpdb->terms AS tter ON (ttax.term_id = tter.term_id) ";
        }
    
        $pieces['distinct'] = 'DISTINCT';
    
        $pieces['orderby'] = "$wpdb->posts.post_date DESC";
      }
    
      return $pieces;
    }
    add_filter( 'posts_clauses', 'myprefix_posts_clauses', 20 );
    
  3. The solution benedikt works fine, but the language filter is with the wpml plugin.
    I use Polylang and looking for the right way to do the same filter, I can not find a solution even with the Polylang documentation…

    There is just this part to change :

        if ( class_exists('WPML_Media') ) {
          global $sitepress;
          //get current language
          $lang = $sitepress->get_current_language();
          $pieces['where'] .= $wpdb->prepare( " AND wpml_translations.element_type='post_attachment' AND wpml_translations.language_code = %s", $lang );
        }
    

    by something like that :

        if ( function_exists( 'pll_current_language' ) ) {
          //get current language
          $lang = pll_current_language();
          $pieces['where'] .= $wpdb->prepare( here I don't know how to write it... );
        }
    

    If someone can help ?