Wordpress search order results - wordpress

Don't know what I'm doing wrong here.
I have a working search function for a property search which I can use to search custom fields. I want to order the search results by price asc and desc using a dropdown filter at the top of the search results.
I have a search.php into which I have placed this code:
<?php include (TEMPLATEPATH . '/search-query.php'); ?>
<form name="formorder" method="post">
<select name="resultsorder" onChange="formorder.submit();">
<option>Order Results By</option>
<option value="Price High-Low" <?php echo ($resultsorder == 'Price High-Low')? 'selected="selected"':''; ?>>Price Low-High</option>
<option value="Price High-Low" <?php echo ($resultsorder == 'Price High-Low')? 'selected="selected"':''; ?>>Price High-Low</option>
<option value="a-z" <?php echo ($resultsorder == 'a-z')? 'selected="selected"':''; ?>>a-z</option>
</select>
</form>
And I have a search-query.php containing this code:
<?php if($resultsorder) {
//get value from order dropdown on search results page
$resultsorder = $resultsorder;
} else {
$resultsorder = get_option('wp_searchorder');}
switch ($resultsorder) {
case "Price High-Low":
$metakey = 'price';
$order = 'DESC';
$orderby = 'meta_value_num';
break;
case "Price Low-High":
$metakey = 'price';
$order = 'ASC';
$orderby = 'meta_value_num';
break;
case "a-z":
$metakey = 'address';
$order = 'ASC';
$orderby = 'meta_value';
break;}
if (!empty($_ids) && !$alllistings) {
$wpq = array ('post_type' => 'listing', 'meta_key' => $metakey, 'orderby' => $orderby, 'order' => $order, 'post__in' => $_ids, 'post_status' => 'publish', 'paged' => $paged, 'posts_per_page' => 9999 );
} elseif (empty($_ids) && !$alllistings) {
// $_ids array is empty because search got no results
// $_ids array will be empty if page is an "All Listings" page. Don't run this code if is All Listings because All Listings will show all listings. This code will display "no results found"
$wpq = array ('post_type' =>'listing', 'meta_key' => $metakey, 'orderby' => $orderby, 'order' => $order, 'post__in' => array('0'),'post_status' => 'publish', 'paged' => $paged, 'posts_per_page' => 9999);
} elseif ($alllistings) {
// This is an All Listings page, so show all results
$wpq = array ('post_type' =>'listing', 'paged' => $paged, 'meta_key' => $metakey, 'orderby' => $orderby, 'order' => $order, 'post_status' => 'publish', 'posts_per_page' => 9999);
}
$listing = new WP_Query($wpq);?>
Not sure what I'm doing wrong.

You'll have to give us a bit more detail. Are you getting an error? If not, what are you expecting to see, and what are you actually seeing?
One possible problem is you're passing "Price High-Low" even if they select "Price Low-High". This line:
<option value="Price High-Low" <?php echo ($resultsorder == 'Price High-Low')? 'selected="selected"':''; ?>>Price Low-High</option>
is wrong.
Edit:
Ok, I've created a simple theme that duplicates what you seem to have. In functions.php I have:
<?php
add_action('init', 'create_listing_post_type');
function create_listing_post_type() {
register_post_type('listing', array(
'labels' => array(
'name' => 'Listings',
'singular_name' => 'Listing',
'add_new_item' => 'Add a listing',
'edit_item' => 'Edit listing',
'new_item' => 'Add a listing',
'search_items' => 'Find a listing',
'not_found' => 'No listing found',
'not_found_in_trash' => 'No listing found in the trash'
),
'public' => true,
'supports' => array('title', 'editor', 'custom-fields')
));
}
?>
I went into the admin screen and added three listings:
Listing A, with an address of "Switzerland" and a price of 10000.
Listing B, with an address of "Australia" and a price of 50000.
Listing C, with an address of "UK" and a price of 20000.
I then added a new template in showlistings.php based on your code:
<?php
/**
* Template Name: showlistings
*/
get_header();
//$resultsorder = 'Price High-Low';
//$resultsorder = 'Price Low-High';
$resultsorder = 'a-z';
switch ($resultsorder) {
case "Price High-Low":
$metakey = 'price';
$order = 'DESC';
$orderby = 'meta_value_num';
break;
case "Price Low-High":
$metakey = 'price';
$order = 'ASC';
$orderby = 'meta_value_num';
break;
case "a-z":
$metakey = 'address';
$order = 'ASC';
$orderby = 'meta_value';
break;
}
$wpq = array (
'post_type' =>'listing',
'meta_key' => $metakey,
'orderby' => $orderby,
'order' => $order);
$listings = new WP_Query($wpq);
foreach( $listings->posts as $listing) {
echo $listing->post_title;
echo '<br />';
}
get_footer(); ?>
The good news is your code works for me: as I changed the value of the $resultsorder (changing the line commented out), I got the results expected.
So that leaves a few things to check:
Is the value of $resultsorder set as you expect (i.e. is it being submitted from your form, and is it being populated from the $_POST variable? put echo "\$resultsorder = $resultsorder"; somewhere in your output to check.
Are the price values stored in a way MySQL can parse them as numbers? For example, "10000", not (say) "$10,000". WordPress has MySQL convert the numbers to strings by adding 0 to them - if they can't be parsed as numbers, they'll all return 0 and any ordering will be meaningless.
Are the $alllistings and $_ids variables populated as you expect (i.e. is the expected branch of your if-then logic being executed? Again, using echo (or print_r) will help you check the values.
Do your string literals match exactly? Might be worth verifying that there are no subtle differences between your form values and the values you're checking in your PHP. You could have similar looking but different characters, or subtle case differences (eg "Price High-Low" vs "Price High-low")
I'd break up your investigation. Check that the form submission is working, then that the query arguments are being set correctly, then that the results are as expected.

Related

WP - insert post only if it does not exist

Background: The custom posts (type: Event) can be added manually by a user (in that case no hq_id meta data is present, or automatically (pulled from another source) by wp_insert_post() (in that case hq_id is present).
Some times the posts can have generic titles so before inserting a post checking if a post of a particular title exists is not sufficient. The idea below is:
Before trying to insert a post from another source and merge it with posts added manually by users the following gets checked:
Does a post of the same title exists?
a) No => Let's insert it (End)
b) Yes.
If Yes: does it have the hq_id meta data and is this equal with hq_id meta of the post that is to be inserted.
a) Yes => ok, that's a duplicate post, no need to insert it
b) No => a post by the same title exists, but the hq_id does not exist or is different, so it's not a duplicate. Let's insert it.
That is fine, until you run the code again. Each time it seems to be adding the posts meeting the 2b condition.
For each re-run of the code, both 2a and 2b are true. I'm not sure why it doesn't exit the if statement after 2a but it still does 2b.
Also, as you'll see the whole $new_post/wp_insert_post code block should be moved to a function as it's being used twice. Where would I put the function definition so I don't have problems with scope?
Here's the code:
if( ! empty( $data_events ) ) {
echo '<ul>';
foreach( $data_events as $event ) {
$title_exists = get_page_by_title( $event['name'], OBJECT, 'event');
if ( $title_exists == null ) {
echo 'Post of the same title does not exist - we need to insert post';
$new_post = array(
'post_title' => $event['name'],
'post_content' => 'desssscccd',
'post_status' => 'publish',
'post_author' => '2',
'post_type' => 'event',
'meta_input' => array(
'hq_id' => $event['id'],
'hq_uri'=> $event['uri'],
)
);
$pid = wp_insert_post($new_post);
wp_set_object_terms($pid, 'riderhq', 'event_category');
} else { // A post of the same title exists
$my_post = get_page_by_title ( $event['name'], OBJECT, 'event' );
$post_hq_id = $my_post->hq_id;
if ( $post_hq_id && $post_hq_id == $event['id'] ) {
echo "post of the same title exists and has the same hq_id - no need to insert it";
} else {
echo "post of the same title exists but doesnt have the same hq_id - we need to insert it";
$new_post = array(
'post_title' => $event['name'],
'post_content' => 'description',
'post_status' => 'publish',
'post_author' => '2',
'post_type' => 'event',
'meta_input' => array(
'hq_id' => $event['id'],
'hq_uri'=> $event['uri'],
)
);
$pid = wp_insert_post($new_post);
wp_set_object_terms($pid, 'riderhq', 'event_category');
}
}
echo '<li>';
echo $event['id'];
echo '' . $event['name'] . '';
echo '</li>';
}
echo '</ul>';
}
I have changed the approach slightly and solved it as follows:
if( ! empty( $data_events ) ) {
function add_event($title, $id, $uri, $event_date) {
$new_post = array(
'post_title' => $title,
'post_content' => 'description',
'post_status' => 'publish',
'post_author' => '2',
'post_type' => 'event',
'meta_input' => array(
'hq_id' => $id,
'hq_uri'=> $uri,
'event_date' => $event_date,
)
);
$pid = wp_insert_post($new_post);
wp_set_object_terms($pid, 'riderhq', 'event_category');
$get_meta_time = get_post_meta($pid, 'event_date');
$newformat = date('Ymd', strtotime($get_meta_time[0]));
update_post_meta($pid, 'event_date', $newformat);
}
foreach( $data_events as $event ) {
$existing_posts_arguments = array(
'hierarchical' => 1,
'meta_key' => 'hq_id',
'meta_value' => $event['id'],
'post_type' => 'event',
);
$existing_posts = get_posts( $existing_posts_arguments );
if ( count($existing_posts) < 1 ) {
add_event($event['name'], $event['id'], $event['uri'], $event['start_date']);
}
} // end of foreach event
}

How can I override BBPress function bbp_has_topics() by adding a filter for this function in Wordpress?

The "bbp_has_topics" function in "public/wp-content/plugins/bbpress/includes/topics/template.php" fetches the topics by "meta_value" in a "Descending" order. I need to override this behaviour to fetch the post by "created date" without editing this file. So is there a way to add a filter for this "bbp_has_topics". I added a filter in functions.php as below. But in the listing page the pagination links are not showing.
function mybbp_has_topics( $args = '') {
$bbp = bbpress();
// Other defaults
$default_topic_search = !empty( $_REQUEST['ts'] ) ? $_REQUEST['ts'] : false;
$default_show_stickies = (bool) ( bbp_is_single_forum() || bbp_is_topic_archive() ) && ( false === $default_topic_search );
$default_post_parent = bbp_is_single_forum() ? bbp_get_forum_id() : 'any';
// The default forum query for most circumstances
$default = array(
'post_type' => bbp_get_topic_post_type(), // Narrow query down to bbPress topics
'post_parent' => $default_post_parent, // Forum ID
'meta_key' => '_bbp_last_active_time', // Make sure topic has some last activity time
'orderby' => 'date', // 'meta_value', 'author', 'date', 'title', 'modified', 'parent', rand',
'order' => 'DESC', // 'ASC', 'DESC'
'posts_per_page' => bbp_get_topics_per_page(), // Topics per page
'paged' => bbp_get_paged(), // Page Number
's' => $default_topic_search, // Topic Search
'show_stickies' => $default_show_stickies, // Ignore sticky topics?
'max_num_pages' => false, // Maximum number of pages to show
);
$r = bbp_parse_args( $args, $default, 'has_topics' );
// Run the query
$bbp->topic_query = new WP_Query( $r );
return apply_filters( 'mybbp_has_topics', $bbp->topic_query->have_posts(), $bbp->topic_query );
}
From my understanding of this, you need to add your filter to the hook in bbp_has_topics.
Something like this function should be added as either in a new plugin or your theme's functions.php.
function mybbp_has_topics($have_posts, $topic_query){
//your code
$default_topic_search = !empty( $_REQUEST['ts'] ) ? $_REQUEST['ts'] : false;
$default_show_stickies = (bool) ( bbp_is_single_forum() || bbp_is_topic_archive() ) && ( false === $default_topic_search );
$default_post_parent = bbp_is_single_forum() ? bbp_get_forum_id() : 'any';
// The default forum query for most circumstances
$default = array(
'post_type' => bbp_get_topic_post_type(), // Narrow query down to bbPress topics
'post_parent' => $default_post_parent, // Forum ID
'meta_key' => '_bbp_last_active_time', // Make sure topic has some last activity time
'orderby' => 'date', // 'meta_value', 'author', 'date', 'title', 'modified', 'parent', rand',
'order' => 'DESC', // 'ASC', 'DESC'
'posts_per_page' => bbp_get_topics_per_page(), // Topics per page
'paged' => bbp_get_paged(), // Page Number
's' => $default_topic_search, // Topic Search
'show_stickies' => $default_show_stickies, // Ignore sticky topics?
'max_num_pages' => false, // Maximum number of pages to show
);
$r = bbp_parse_args( $args, $default, 'has_topics' );
// Run the query
$topic_query = new WP_Query( $r );
return $topic_query;}
add_filter( 'bbp_has_topics', mybbp_has_topics, 99, 2);
the parameter $topic_query contains the query that was made in bbp_has_topics.

Setting a default option using CMB2 select field type

I am using CMB2's select to pull in a list of posts that a user can choose from in a custom meta box.
I have added a "blank" option to the options array, but I can't figure out how to make that the default option (ie. <option selected="selected" value="">I'm blank</option>).
I need to do this so I can use an if statement that says if the field is blank, don't show the output box on the site. Right now, even if the user hasn't specifically chosen an option, an option with a value is passed through.
Here's the meta box code:
$link_post_types = array('charter', 'page');
$meta_boxes['ms_metabox'] = array(
'id' => 'ms_metabox',
'title' => __( 'Page Links', 'cmb2' ),
'object_types' => array( 'page' ),
'context' => 'normal',
'priority' => 'high',
'show_names' => true,
'fields' => array(
array(
'name' => __( 'Page Link', 'cmb2' ),
'desc' => __( 'Choose the page this will link to', 'cmb2' ),
'id' => $prefix . 'page_link',
'type' => 'select',
'options' => ms_get_posttype_options($link_post_types),
),
),
);
function ms_get_posttype_options($argument) {
$get_post_args = array(
'post_type' => $argument,
'posts_per_page' => -1,
'orderby' => 'type',
'order' => ASC
);
$options = array();
foreach ( get_posts( $get_post_args ) as $post ) {
$post_type = get_post_type( $post->ID);
$title = get_the_title( $post->ID );
$permalink = get_permalink( $post->ID);
$options[] = array(
'name' => $title . ' : ' . $post_type,
'value' => $permalink,
);
}
$empty_option[] = array(
'name' => 'Please select an option',
'value' => '',
);
$options = array_merge($empty_option, $options);
return $options;
}
There is a default argument but when I tried to apply it as in the example, it didn't work.
Thanks for any help!
I halfway figured it out. The posts I was having problems with were old ones where I had already been messing with the values before I added the blank option - when I created new posts, the default option was the blank one (since it was the first array in the merge).
If anyone has a more foolproof solution I'd like to hear it though!
You can add the following to the meta box fields array:
show_option_none' => true

WordPress: Show authors of taxonomy in order of post count

i want to show a list of authors of a taxonomy and order the list by the post count.
At the end, i want to show images of the authors with different sizes depending of their post count.
Here is what i have (source: http://blog.brianjohnsondesign.com/dropdown-list-of-authors-with-posts-in-category/):
<ul>
<?php //Code to get a list of all authors with posts in this category, and then create a dropdown list of their names with links to their page
$category = get_queried_object();
$taxonomy_name = 'themen'; //Change to reflect the name of your custom taxonomy
$current_category = $category->slug;
$author_array = array();
$args = array(
'posts_per_page' => -1,
'post_type' => 'post', //Change to your custom post type
'tax_query' => array(
array(
'taxonomy' => 'themen', //Change to reflect the name of your custom taxonomy
'field' => 'slug',
'terms' => $current_category
),
),
'orderby' => 'author',
'order' => 'ASC'
);
$cat_posts = get_posts($args);
foreach ($cat_posts as $cat_post) :
if (!in_array($cat_post->post_author,$author_array)) {
$author_array[] = $cat_post->post_author;
}
endforeach;
foreach ($author_array as $author) :
$auth = get_userdata($author)->display_name;
$nicename = get_userdata($author)->user_nicename;
//echo '<li>' . $auth . '</li>';
echo '<li>' . $auth . '</li>';
endforeach;
?>
</ul>
Is this the right direction?
I am not sure how i can order the authors. :(
You can definitely use the WP query for this. WordPress query is a very powerful tool if you use it properly. Or you can just list the authors using WP function called list_authors
<?php wp_list_authors( $args ); ?>
<?php $args = array(
'orderby' => 'post_count',
'order' => 'DESC',
'number' => null,
'optioncount' => false,
'exclude_admin' => true,
'show_fullname' => false,
'hide_empty' => true,
'echo' => true,
'feed' => [empty string],
'feed_image' => [empty string],
'feed_type' => [empty string],
'style' => 'list',
'html' => true,
'exclude' => [empty string],
'include' => [empty string] ); ?>

Attach image to post in Wordpress XMLRPC

I am using XMLRPC to do posts to Wordpress. I am having issues posting thumbnails, after debugging wordpress code I see that my issue is caused by the fact that the image is not attached to the post.
I must do this without patching wordpress or using PHP, only iwth XMLRPC.
I can upload an image and get the ID of the image.
Other point that confuses me is how do you attach an image to a post that you did not posted yet because you wait for the image to upload? I am supposed to upload image then post ,then using the image id and the post id do an update on the image metadata?
Edit: the code in wordpress that is problematic is this check
if ( $thumbnail_html = wp_get_attachment_image( $thumbnail_id, 'thumbnail' ) )
and my assumption it is that it fails because the image is Unattached, if i fix that code all is fine but I can't patch the WP of my application users(so this is not a solution)
Yes it is possible to do it, if Wordpress version is 3.5 or greater,when using the code for uploading file/image you can set the post_id.
The flow I used for new posts with featured images is like this:
use the newPost function and post the content without the featured
image and also set publish to false, record the post_id returned by
this
upload the image and set the post_id to the id of the post just
posted, record the image_id
when done edit the post and set the wp_post_thumbnail equal to the
image_id you just uploaded and also set publish to true(if needed)
Important:
The mime type is important, it must be "image/jpg" or "image/png" please see documentation, if mime type is worng like "jpg" attaching will fail.
Tip:
For debugging, if you get a generic error from wordpress and you can't figure out why you can check the wordpress code and even edit it, adding debugging/tracing calls and hopefully you can figure out the cause.
This is an example of a post with category, image and tags. It requires class-IXR.php
https://github.com/WordPress/WordPress/blob/master/wp-includes/class-IXR.php
and mime_content_type function
https://github.com/caiofior/storebaby/blob/master/magmi/plugins/extra/general/socialnotify/wp/mimetype.php
$client = new IXR_Client($url);
$content = array(
'post_status' => 'draft',
'post_type' => 'post',
'post_title' => 'Title',
'post_content' => 'Message',
// categories ids
'terms' => array('category' => array(3))
);
$params = array(0, $username, $password, $content);
$client->query('wp.newPost', $params);
$post_id = $client->getResponse();
$content = array(
'name' => basename('/var/www/sb/img.jpeg'),
'type' => mime_content_type('/var/www/sb/img.jpeg'),
'bits' => new IXR_Base64(file_get_contents('/var/www/sb/img.jpeg')),
true
);
$client->query('metaWeblog.newMediaObject', 1, $username, $password, $content);
$media = $client->getResponse();
$content = array(
'post_status' => 'publish',
// Tags
'mt_keywords' => 'tag1, tag2, tag3',
'wp_post_thumbnail' => $media['id']
);
$client->query('metaWeblog.editPost', $post_id, $username, $password, $content, true);
My version if you want to use only wp.newPost and wp.editPost
include_once( ABSPATH . WPINC . '/class-IXR.php' );
include_once( ABSPATH . WPINC . '/class-wp-http-ixr-client.php' );
$usr = 'username_on_the_server_side';
$pwd = 'password_on_the_server_side';
$xmlrpc = 'server side xmlrpc.php url';
$client = new IXR_Client($xmlrpc);
//////////// IMAGE UPLOAD AND ATTACHMENT POST CREATION ///////////
$img_attach = 'link to the image';
$img_attach_content = array(
'name' => basename($img_attach),
'type' => mime_content_type($img_attach),
'bits' => new IXR_Base64(file_get_contents($img_attach)),
);
$status = $client->query( 'wp.uploadFile','1', $usr, $pwd, $img_attach_content );
$image_returnInfo = $client ->getResponse();
//////////// POST CREATION ///////////
$custom_fields = array(
array( 'key' => 'blabla1', 'value' => 'blabla1_value' ),
array( 'key' => 'blabla12', 'value' => 'blabla1_value2')
);
$post_content = array(
'post_type' => 'post',
'post_status' => 'draft', //for now
'post_title' => 'XMLRPC Test',
'post_author' => 3,
'post_name' => 'XMLRPC Test',
'post_content' => 'XMLRPC Test Content',
'custom_fields' => $custom_fields
);
$res = $client -> query('wp.newPost',1, $usr, $pwd, $post_content);
$postID = $client->getResponse();
if(!$res)
echo 'Something went wrong....';
else {
echo 'The Project Created Successfully('.$res.')<br>Post ID is '.$postID.'<br>';
}
//////////// Image Post Attachment Edit ///////////
$img_attach_content2 = array(
'post_type' => 'attachment',
'post_status' => 'inherit',
'post_title' => $postID,
'post_name' => $postID,
'post_parent' => $postID,
'guid' => $image_returnInfo['url'],
'post_content' => '',
'post_mime_type' => 'image/jpg'
);
$res2 = $client -> query('wp.editPost', 0, $usr, $pwd, $image_returnInfo['id'], $img_attach_content2);
$postIDimg = $client->getResponse();
//////////// POST EDIT ///////////
$post_content2 = array(
'post_status' => 'publish', //publish
'wp_post_thumbnail' => $image_returnInfo['id'],
'custom_fields' => array( 'key' => '_thumbnail_id', 'value' => $image_returnInfo['id'] )
);
$media2= $client->query('wp.editPost',0, $usr, $pwd, $postID, $post_content2);
This is my version, using wp.newPost and wp.editPost, added on WordPress 3.4, that allow the use of custom post types.
require_once("IXR_Library.php.inc");
$title = 'My title';
$body = 'My body';
$category="category1, category2"; // Comma seperated pre existing categories. Ensure that these categories exists in your blog.
$keywords="keyword1, keyword2, keyword3";
$customfields=array('key'=>'Author-bio', 'value'=>'Autor Bio Here'); // Insert your custom values like this in Key, Value format
$title = htmlentities($title,ENT_NOQUOTES,#$encoding);
$keywords = htmlentities($keywords,ENT_NOQUOTES,#$encoding);
$content = array(
'post_title'=>$title,
'post_content'=>$body,
'post_type'=>'some_custom_post_type',
'post_status' => 'draft', // http://codex.wordpress.org/Post_Status
'mt_allow_comments'=>0, // 1 to allow comments
'mt_allow_pings'=>0, // 1 to allow trackbacks
'mt_keywords'=>$keywords,
'categories'=>array($category),
'custom_fields' => array($customfields)
);
// Create the client object
$client = new IXR_Client('http://example.com/xmlrpc.php');
$username = "wp_username";
$password = "wp_username_password";
$params = array(0,$username,$password,$content,true); // Last parameter is 'true' which means post immediately, to save as draft set it as 'false'
if (!$client->query('wp.newPost', $params)) {
die('<br/><strong>Something went wrong - '.$client->getErrorCode().' : '.$client->getErrorMessage().'<br >');
}
else
{
$post_id = $client->getResponse();
echo 'Inserted with id'.$post_id;
$picture = '/full/path/to/pic.jpg';
$content = array(
'name' => basename($picture),
'type' => mime_content_type($picture),
'bits' => new IXR_Base64(file_get_contents($picture)),
true
);
if (!$client->query('metaWeblog.newMediaObject', 1, $username, $password, $content)) {
die('<br/><strong>Something went wrong - newMediaObject'.$client->getErrorCode().' : '.$client->getErrorMessage().'<br >');
}
else
{
$media = $client->getResponse();
$content = array(
'post_status' => 'publish',
'post_thumbnail' => $media['id']
);
if (!$client->query('wp.editPost', 0, $username, $password, $post_id, $content)) {
die('<br/><strong>Something went wrong editPost - '.$client->getErrorCode().' : '.$client->getErrorMessage().'<br >');
}
}
}

Resources