Johan Davidsson
Johan Davidsson

Reputation: 2972

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.

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

Upvotes: 1

Views: 1954

Answers (4)

Pierre Ferron
Pierre Ferron

Reputation: 11

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 ?

Upvotes: 0

benedikt
benedikt

Reputation: 1989

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 );

Upvotes: 0

Sabari
Sabari

Reputation: 6335

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

Upvotes: 2

Joshua Walcher
Joshua Walcher

Reputation: 496

This plugin's changelog page says that it searches media tags added by its program: http://wordpress.org/plugins/media-tags/changelog/

If you're building your own plugin, I recommend grabbing their code and seeing what they're doing. Otherwise, their plugin seems to be exactly what you're looking for.

Upvotes: 0

Related Questions