Getting Links in Multiple Categories (intersection)

I am using get_bookmarks() to get bookmark links. I can get links posted in cat A or cat B, but I only want links in both A and B.

Example what I need:

Read More

I have three link categories cat#1, cat#2, cat#3.

I need to get links in both cat#1 AND cat#2 not cat#1 OR cat#2 (intersection).

I am currently using:

$links = get_bookmarks(array('category' => $term_ids));

Which doesn’t work because of how get_bookmarks() works.

        $category_query = '';
        $join = '';
        if ( !empty($category) ) {
                $incategories = preg_split('/[s,]+/',$category);
                if ( count($incategories) ) {
                        foreach ( $incategories as $incat ) {
                                if (empty($category_query))
                                        $category_query = ' AND ( tt.term_id = ' . intval($incat) . ' ';
                                else
                                        $category_query .= ' OR tt.term_id = ' . intval($incat) . ' ';
                        }
                }
        }

Note from the Editor: Adding sample code for easier understanding – Bookmarks get queried with an OR clause by default. As they’re retrieved via $wpdb->get_result(), there’s no easy solution in filtering aside from the queried result.

Any help or idea of different approach would be much appreciated.

UPDATE

I am trying to make a new function out of get_bookmarks() function.

I changed the code that shown above to this below (changed OR to AND). But now nothing is returning. Perhaps i need to change the SQL to something else. So, I will need advice on this.

if ( !empty($category) ) {
        $incategories = preg_split('/[s,]+/',$category);
        if ( count($incategories) ) {
            foreach ( $incategories as $incat ) {
                if (empty($category_query))
                    $category_query = ' AND ( tt.term_id = ' . intval($incat) . ' ';
                else{
                    // sisir
                    $category_query .= ' AND tt.term_id = ' . intval($incat) . ' ';
                }
            }
        }
    }

Related posts

Leave a Reply

3 comments

  1. It should be as simple as that: Just get the terms from the link_category and use the get_terms() argument instead, which should work like you need it.

    get_terms(
         'link_category'
        ,array(
             'include'      => array( 1, 2, 3 )
            ,'orderby'      => 'name'
            ,'order'        => 'ASC'
            ,'hierarchical' => 0
         )
    );
    
  2. Forking get_bookmarks() seems troublesome, I’d code out a bit (and cache if it gets slow). Something like this:

    /**
     * Retrieve links that have all of the terms assigned.
     * 
     * @param array $term_ids
     *
     * @return array of link objects
     */
    function get_bookmarks_in_terms( $term_ids ) {
    
        $bookmark_ids = array();
    
        foreach ( $term_ids as $term_id ) {
    
            $bookmarks_in_term = get_objects_in_term( $term_id, 'link_category' );
    
            if ( empty( $bookmarks_in_term ) )
                return array();
    
            if ( empty( $bookmark_ids ) )
                $bookmark_ids = $bookmarks_in_term;
            else
                $bookmark_ids = array_intersect( $bookmark_ids, $bookmarks_in_term );
        }
    
        if ( empty( $bookmark_ids ) )
            return array();
    
        return get_bookmarks( array( 'include' => implode( ',', $bookmark_ids ) ) );
    }
    
  3. Use get_objects_in_term to grab all objects using those terms so somethign similar to this:

    $objects = get_objects_in_term($term_ids,'link_category');
    $links = get_bookmarks(array('include' => $objects ));