WordPress get_post_meta_multiple, Pagination and Ordering.

Dealing with wordpress.

Because of seo power of wordpress almost every my project I’m using wordpress.
According to me wordpress is single but powerful framework.

Maybe you already know about Custom Field Taxonomies in wordpress.
It was pretty simple Custom Field Filter plug in.

I use it lots of project that I manage.
And also I was pretty happy with this plug in.

But after that 1.4 version they changed their direction of Custom Field Taxonomies from custom fields to tags.

As Custom Field Taxonomies alternative I searched near all of web.

Found 3 function as alternative.

wordpress -> query_posts() was good function. But not supporting multiple filters.

I found get_post_meta_multiple function thanks to the Jamie.

and get_post_meta_multiple (modified version of first) thanks to the Matt

Matt’s function was almost near the function that I looking for. But it was not supporting Order by, Order as, and Pagination also some problems about null category.
You can see both pages people are asking about these, (me to :) )

I took some help from codes of Jignesh Patel he has also another code to Pagination but I do not like it. to complicated.

Lastly I modified all of them (spend two days on it)

Hope to helps someone.

usage

<?php
$aMetaDataList = array('type' => 'Flat', 'for' => 'Sale');
global $resultList;
    $szCategory = 'NULL'; // All Categories will be shown, $szCategory = '1,2,3'; Only from 1,2,3
    $ppp = 5; // Post per page.
    $metaKey = 'total_property_size'; // Metakey to order.
    $orderBy = 'desc'; // orderBy = 'asc'; for Ascending
    $orderType = 'numerical'; // Order as Numerical, $orderType = 'Aphabetical'; Leave Blank Alphabetical
    $resultList = get_post_meta_multiple( $aMetaDataList, 'post', $szCategory, $ppp, $metaKey, $orderBy, $orderType);
?>

function comes here.

<?php 
function get_post_meta_multiple( $aMetaDataList = array(), $szType = 'post', $szCategory = NULL, $ppp, $metaKey, $orderBy, $orderType)
{
    /**
     * @author Modified by Deniz Netinial.com
     * @copyright deniz [at] porsuk dot net
     * to modify I spend 1 week on it.
     * If you like this modification just send me an e mail, with thanks. SQL_NO_CACHE
     */
 
    global $wpdb,$wp_query;
    $szQuerystr = "SELECT SQL_Calc_Found_Rows $wpdb->posts.* FROM $wpdb->posts ";
 
    if ( $szCategory != NULL AND is_string($szCategory) )
    {
    $szQuerystr .= " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) ";
    $szQuerystr .= " INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) ";
    }
    $szQuerystr .= " JOIN $wpdb->postmeta on ($wpdb->posts.ID = $wpdb->postmeta.post_id) WHERE ";
 
    if ( $szCategory != 'NULL' AND is_string($szCategory) )
    {
    $szQuerystr .= " 1=1 AND $wpdb->term_taxonomy.taxonomy = 'category' ";
    $szQuerystr .= " AND $wpdb->term_taxonomy.term_id IN(".$szCategory.")  AND ";
    }
 
    $szQuerystr .= " $wpdb->posts.post_type = '".$szType."' AND $wpdb->posts.post_status = 'publish'";
 
    if($metaKey){
    $szQuerystr .= " AND $wpdb->postmeta.meta_key = '".$metaKey."' ";
    }
 
    $aInnerqry = array();
 
    if(!empty($aMetaDataList))
    {
        $szQuerystr .= " Group By  $wpdb->posts.ID Having ";
        $szQuerystr .= " $wpdb->posts.ID IN (";
        $szQuerystr .= "SELECT $wpdb->postmeta.post_id FROM $wpdb->postmeta WHERE ";
        foreach($aMetaDataList as $szKey => $szValue)
        {
        $aInnerqry[] = $wpdb->prepare( "(meta_key = %s AND meta_value = %s)", $szKey, $szValue );
        }
    $szQuerystr .= implode(" OR ", $aInnerqry);
    $szQuerystr .= " GROUP BY $wpdb->postmeta.post_id ";
    $szQuerystr .= " HAVING count(*) = " . count($aMetaDataList)." ) ";
    }
 
    if(strtolower($orderType) == 'numerical')
      { $orderType = 'ABS'; }
    else { $orderType = ''; }
 
    if(!empty($aMetaDataList)) { $szQuerystr .= " ORDER BY ".$orderType."($wpdb->postmeta.meta_value) "; }
    else {  $szQuerystr .= " ORDER BY $wpdb->posts.post_date "; }
 
    if($orderBy == strtolower('desc')){ $szQuerystr .= " desc "; }else{ $szQuerystr .= " asc "; }
 
     # put limit in query built above */

    $aMetaResults = $wpdb->get_results($szQuerystr, OBJECT);
 
    if(!$ppp or !is_int($ppp))
    { $ppp = intval(get_query_var('posts_per_page')); } //12 posts per page you might use $ppp = intval(get_query_var('posts_per_page'));
 
    $wp_query->found_posts = count($aMetaResults);
    $wp_query->max_num_pages = ceil($wp_query->found_posts / $ppp);
    $on_page = intval(get_query_var('paged'));
    if($on_page == 0){ $on_page = 1; }
    $offset = ($on_page-1) * $ppp;
 
    $wp_query->request = $szQuerystr." LIMIT $ppp OFFSET $offset ";
    $pageposts = $wpdb->get_results($wp_query->request, OBJECT);
 
    echo mysql_error();
 
    echo ' --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- '.$szQuerystr;
 
    return $pageposts;
}
?>

and the loop

<?php
if ($resultList):
//Loop through each result post to display appropriate contents
$i = 0;
foreach ($resultList as $post):
	setup_postdata($post);
        echo '<h1>'.$resultList[0]->ID.'</h1>';
endforeach;
?>

Here is the second version of this codes.



8 Responses to “WordPress get_post_meta_multiple, Pagination and Ordering.”

  1. scribu says:

    Hi Deniz,

    It seems several people also missed the old version of the plugin, so I started writing a new one:

    http://wordpress.org/extend/plugins/query-custom-fields/

  2. deniz says:

    We will be glad to see your plugin, scribu.

    Custom fields has more sharp rules according to tags. It will be better for much people.

  3. Anthony says:

    This is exactly what I need thank you!

    However, I am having an issue getting it to work. I was able to get Jamie’s original version to work fine, but I need the page per post settings.

    I keep getting the “No posts found” from the else statement.

    I am trying to query the custom fields from a custom post type, does something else need to be changed? I tried changing the $szType argument to my custom post type, but no luck.

    Also, do the $orderBy, $orderType, and $metaKey need to be set? or can they be left blank?

    Any help would be greatly appreciated.

  4. deniz says:

    Dear Anthony,

    You can use post per page settings like
    $ppp = 10;
    variable before calling function

    Three variable enough to change.

    $aMetaDataList = array(
    ‘t’ => ‘Flat’,
    ‘for’ => ‘Sale’);

    $metaKey = ‘total_property_size’;

    I have checked code for lots of calling type even you leave the $orderBy, $orderType, and $metaKey blank it must work.

    I modified code for performance, and some security issues you can take new version.

    Note for every one to make it work function you have to replace all ” – & g t ; ” (no blanks) to “->” .

    This error just because of wordpress plugin.

    Deniz

  5. Anthony says:

    Thanks for your help, it’s coming along!

    However, I’ve hit another little snag…

    I am using the get_post_meta_multiple function several times on the same page to call different posts (with different post types).

    I realize that this is sending my page queries into the unacceptable range (160-230).

    Is there a way that I can display these different post types by their custom fields without having to generate so many queries? Perhaps rewind posts?

    Thanks for all your help.

  6. deniz says:

    Dear Anthony,

    After I took the code,
    I made so much changes on it.

    I can say that. It is using same method with wordpress category filter.

    When you call query_posts(‘category=5′);

    It is making same work on wordpress. My offer is using wp super cache or similar plug in.

  7. sandeep shrestha says:

    hi,

    the plugin is working but its not listing all the post under that query, its showing just few, can you please help me deniz

Leave a Reply