Adding search term to current query (Wordpress PHP) - php

Currently I've got this bit of code to do post-per-page filter to my woocommerce shop
function ps_selectbox() {
$per_page = filter_input(INPUT_GET, 'perpage', FILTER_SANITIZE_NUMBER_INT);
ob_start();
echo '<div class="woocommerce-ordering">';
echo '<select onchange="if (this.value) window.location.href=this.value">';
$orderby_options = array(
'16' => '16 items per page',
'32' => '32 items per page',
'64' => '64 items per page'
);
foreach( $orderby_options as $value => $label ) {
echo "<option ".selected( $per_page, $value )." value='?perpage=$value'>$label</option>";
}
echo '</select>';
echo '</div>';
return ob_get_clean();
}
add_action( 'pre_get_posts', 'ps_pre_get_products_query' );
function ps_pre_get_products_query( $query ) {
$per_page = filter_input(INPUT_GET, 'perpage', FILTER_SANITIZE_NUMBER_INT);
if( $query->is_main_query() && !is_admin() ) {
$query->set( 'posts_per_page', $per_page );
}
}
It will append "?perpage=$value" to the url and change number of items per page in the shop.
But when it comes to search result page, it will clear the current query and replace it with just "?perpage=$value"
EX: "https://aaa.com/?s=C21&post_type=product" to "https://aaa.com/?perpage=16"
If I manually change the url to be ""https://aaa.com/?s=C21&post_type=product&perpage=32" it works.
I tried add_query_arg( $args ) and a condition check but it doesn't seem to work.
EX:
function ps_pre_get_products_query( $query ) {
$per_page = filter_input(INPUT_GET, 'perpage', FILTER_SANITIZE_NUMBER_INT);
if (is_search()) {
add_query_arg( $per_page );
}
elseif( $query->is_main_query() && !is_admin() ) {
$query->set( 'posts_per_page', $per_page );
}
}
But it doesn't seem to work.
Is there anyway I can keep this perpage dropdown feature in search result page?
Thanks in advance. Cheers.

Related

Sortable columns in Wordpress for a Custom Post Type

I'm working on the admin side for a Wordpress site. I have a CPT that I've added a column into and would like to sort by that column type. Based off what I've read I'm using the correct functions, but after the filter of 'manage_edit-leadership_sortable_columns' there are no changes to the admin UI. This a CPT and the hierarchy is set to 'True.' I'd read that that may affect it but couldn't find a fix. The column also appears with a red circle and '0' next to it, that I don't know where it came from. The eventual goal is to set the display page on the site to the menu order and give the client the option to sort either by Title or Last Name. Thanks!
add_filter( 'manage_leadership_posts_columns', 'smashing_filter_posts_columns' );
function smashing_filter_posts_columns( $columns ) {
$name = array();
$name['last_name'] = __( 'Last Name', 'smashing', true );
array_splice($columns, 2, 0, $name);
return $columns;
}
function smashing_leadership_column( $column, $post_id ) {
// Name column
if ( 'last_name' == $column ) {
$lastName = get_field('last_name', $post_id );
echo $lastName;
}
}
add_action( 'manage_leadership_posts_custom_column', 'smashing_leadership_column', 10, 2);
function smashing_leadership_sortable_columns( $columns ) {
$columns['last_name'] = 'last_name';
return $columns;
}
add_filter( 'manage_edit-leadership_sortable_columns', 'smashing_leadership_sortable_columns');
add_action( 'pre_get_posts', 'smashing_posts_orderby' );
function smashing_posts_orderby( $query ) {
if( ! is_admin() || ! $query->is_main_query() ) {
return;
}
if ( 'last_name' === $query->get( 'orderby') ) {
$query->set( 'orderby', 'meta_value' );
$query->set( 'meta_key', 'last_name' );
}
}
Admin Screenshot
I was able to get this to work with the following code in place of the other sortable filters.
add_filter( 'manage_edit-leadership_sortable_columns', 'my_sortable_leadership_columns' );
function my_sortable_leadership_columns( $columns ) {
$columns['firstName'] = 'first';
$columns['lastName'] = 'last';
return $columns;
}
add_action( 'pre_get_posts', 'my_leadership_orderby' );
function my_leadership_orderby( $query ) {
if( ! is_admin() )
return;
$orderby = $query->get( 'orderby');
if( 'first' == $orderby ) {
$query->set('meta_key','first_name');
$query->set('orderby','meta_value');
}
if( 'last' == $orderby ) {
$query->set('meta_key','last_name');
$query->set('orderby','meta_value');
}
}

Woocommerce shop orderby=RANDOM, how to prevent products from repeating when going to a different page using pagination

Essentialy I have a working code in functions which displays products randomly for an assigned category. The issue is that when the products are displayed , if it has pagination, the products show repetitions, in page 2 / 3 /...
Im trying to prevent this from happening .
Ive tried implementing to my working code from a plugin that does just that, but not for category specific.
So im trying to randomize the order of products for a specific category. This is the code that does it (but with repetition in page 2/3/...)
function custom_catalog_ordering_args_8( $args ) {
$product_category = 'best-sellers';
if( ! is_product_category($product_category) ) return $args;
// Set default ordering to 'date ID', so "Newness"
$args['orderby'] = 'rand';
if( $args['orderby'] == 'date ID' )
$args['order'] = 'DESC'; // Set order by DESC
return $args;
}
add_filter( 'woocommerce_get_catalog_ordering_args', 'custom_catalog_ordering_args_8', 20, 1 );
Now below is the code from the plugin which prevents products from repeating by creating a transient life of one hour
`
//add "Random" setting to product sorting menu
function do2_addRandomProductOrderSetting($sortby){
$sortby['random_order'] = 'Random';
return $sortby;
}
add_filter('woocommerce_default_catalog_orderby_options','do2_addRandomProductOrderSetting');
add_filter('woocommerce_catalog_orderby','do2_addRandomProductOrderSetting');
//randomize products when setting is used
function do2_randomizeProductWhenSet($args){
$orderbySetting = isset($_GET['orderby']) ? wc_clean($_GET['orderby']) : apply_filters('woocommerce_default_catalog_orderby', get_option('woocommerce_default_catalog_orderby'));
if('random_order' == $orderbySetting){
if(false===($seed = get_transient('do2_randSeed'))){
$seed = rand();
set_transient('do2_randSeed', $seed, 3600 );
}
$args['orderby'] = 'RAND('.$seed.')';
$args['order'] = '';
$args['meta_key'] = '';
}
return $args;
}
add_filter('woocommerce_get_catalog_ordering_args','do2_randomizeProductWhenSet');
}
} else {
if(!function_exists('do2_WooCommerceAdminNotice')){
//warn on missing WooCommerce
function do2_WooCommerceAdminNotice() {
?>
<div class="notice error is-dismissible" >
<p><?php _e('Your site must be running WooCommerce to benefit from the WooCommerce Random Product Sorting with Pagination plugin.'); ?></p>
</div>
<?php
}
add_action('admin_notices', 'do2_WooCommerceAdminNotice');
}
And below is the implementation of it i tried to do to make it to work for a specific category, in this case "best-sellers", but It doesn't work at all
function do2_randomizeProductWhenSet($args){
$product_category = 'best-sellers';
if( ! is_product_category($product_category) ) return $args;
$orderbySetting = isset($_GET['orderby']) ? wc_clean($_GET['orderby']) :
apply_filters('woocommerce_default_catalog_orderby',
get_option('woocommerce_default_catalog_orderby'));
if( ! is_product_category($product_category) == $orderbySetting){
if(false===($seed = get_transient('do2_randSeed'))){
$seed = rand();
set_transient('do2_randSeed', $seed, 3600 );
}
$args['orderby'] = 'RAND('.$seed.')';
if( $args['orderby'] == 'date ID' )
$args['order'] = 'DESC'; // Set order by DESC
}
return $args;
}
add_filter('woocommerce_get_catalog_ordering_args','do2_randomizeProductWhenSet');
Anyone please?? Much appreciated !
I hope this helpful
session_start();
$seed = $_SESSION['seed'];
if (empty($seed)) {
$seed = rand();
$_SESSION['seed'] = $seed;
}
$sortby = 'RAND('.$seed.')';
$atts = array(
'orderby' => $sortby,
'per_page' => $per_page,//your limit products per page
'page' => $paged, // your num page pagination
);
$shortcode = new WC_Shortcode_Products($atts, 'recent_products');
echo $shortcode->get_content();

adding a products per page dropdown to woocommerce

I'm trying to add a 'products per page' dropdown to my woocommerce storefront child theme without using a plugin. I'm adding the below code to my functions.php source
add_action( 'woocommerce_before_shop_loop', 'ps_selectbox', 25 );
function ps_selectbox() {
$per_page = filter_input(INPUT_GET, 'perpage', FILTER_SANITIZE_NUMBER_INT);
echo '<div class="woocommerce-perpage">';
echo '<span>Per Page: </span>';
echo '<select onchange="if (this.value) window.location.href=this.value">';
$orderby_options = array(
'8' => '8',
'16' => '16',
'32' => '32',
'64' => '64'
);
foreach( $orderby_options as $value => $label ) {
echo "<option ".selected( $per_page, $value )." value='?perpage=$value'>$label</option>";
}
echo '</select>';
echo '</div>';
}
add_action( 'pre_get_posts', 'ps_pre_get_products_query' );
function ps_pre_get_products_query( $query ) {
$per_page = filter_input(INPUT_GET, 'perpage', FILTER_SANITIZE_NUMBER_INT);
if( $query->is_main_query() && !is_admin() && is_post_type_archive( 'product' ) ) {
$query->set( 'posts_per_page', $per_page );
}
}
When I do this, the drop down box shows but any option I choose just takes me back to the front page of my theme.
Can anyone help me?
You can add the below codes into functions.php file. Reference:
The first step is to display a select box on the shop archive page. With some basic php we can echo a select box via the woocommerce_before_shop_loop hook.
add_action( 'woocommerce_before_shop_loop', 'ps_selectbox', 25 );
function ps_selectbox() {
$per_page = filter_input(INPUT_GET, 'perpage', FILTER_SANITIZE_NUMBER_INT);
echo '<div class="woocommerce-perpage">';
echo '<span>Per Page: </span>';
echo '<select onchange="if (this.value) window.location.href=this.value">';
$orderby_options = array(
'8' => '8',
'16' => '16',
'32' => '32',
'64' => '64'
);
foreach( $orderby_options as $value => $label ) {
echo "<option ".selected( $per_page, $value )." value='?perpage=$value'>$label</option>";
}
echo '</select>';
echo '</div>';
}
Some inline jQuery has been added so everytime the select box is changed the “products per page” varibale is sent to the browser.
The filter_input() function gets the external variable which in this case is the number of products to show and sanitizes it.
Now everything is in place we can run the pre_get_posts hook with number of products per page via the “get” method.
add_action( 'pre_get_posts', 'ps_pre_get_products_query' );
function ps_pre_get_products_query( $query ) {
$per_page = filter_input(INPUT_GET, 'perpage', FILTER_SANITIZE_NUMBER_INT);
if( $query->is_main_query() && !is_admin() && is_post_type_archive( 'product' ) ){
$query->set( 'posts_per_page', $per_page );
}
}
This is the most simpliest of methods to add a “products per page” dropdown for your WooCommerce store, alternativle you could go about using an ajax method.
I'm using the following code taken from here-
http://designloud.com/how-to-add-products-per-page-dropdown-to-woocommerce/?showmodaldialog=1#comment-1554
// Lets create the function to house our form
remove_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30 );
function woocommerce_catalog_page_ordering() {
?>
<?php echo '<span class="itemsorder">Items Per Page:' ?>
<form action="" method="POST" name="results" class="woocommerce-ordering">
<select name="woocommerce-sort-by-columns" id="woocommerce-sort-by-columns" class="sortby" onchange="this.form.submit()">
<?php
//Get products on page reload
if (isset($_POST['woocommerce-sort-by-columns']) && (($_COOKIE['shop_pageResults'] <> $_POST['woocommerce-sort-by-columns']))) {
$numberOfProductsPerPage = $_POST['woocommerce-sort-by-columns'];
} else {
$numberOfProductsPerPage = $_COOKIE['shop_pageResults'];
}
// This is where you can change the amounts per page that the user will use feel free to change the numbers and text as you want, in my case we had 4 products per row so I chose to have multiples of four for the user to select.
$shopCatalog_orderby = apply_filters('woocommerce_sortby_page', array(
//Add as many of these as you like, -1 shows all products per page
// '' => __('Results per page', 'woocommerce'),
'20' => __('20', 'woocommerce'),
'-1' => __('All', 'woocommerce'),
));
foreach ( $shopCatalog_orderby as $sort_id => $sort_name )
echo '<option value="' . $sort_id . '" ' . selected( $numberOfProductsPerPage, $sort_id, true ) . ' >' . $sort_name . '</option>';
?>
</select>
</form>
<?php echo ' </span>' ?>
<?php
}
// now we set our cookie if we need to
function dl_sort_by_page($count) {
if (isset($_COOKIE['shop_pageResults'])) { // if normal page load with cookie
$count = $_COOKIE['shop_pageResults'];
}
if (isset($_POST['woocommerce-sort-by-columns'])) { //if form submitted
setcookie('shop_pageResults', $_POST['woocommerce-sort-by-columns'], time()+1209600, '/', 'www.your-domain-goes-here.com', false); //this will fail if any part of page has been output- hope this works!
$count = $_POST['woocommerce-sort-by-columns'];
}
// else normal page load and no cookie
return $count;
}
add_filter('loop_shop_per_page','dl_sort_by_page');
add_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_page_ordering', 20 );

Woocommerce category text

I am trying to upgrade my SEO on my webshop. Anyone knows php could fix this puzzle. How can i fit this in each other?
How does this: is_product_category( 'shirts' ) fit in this:
function woa_content_before_shop() {
echo "<p>Insert your Content here...</p>";
}
add_action( 'woocommerce_before_shop_loop', 'woa_content_before_shop');
WordPress conditional tags like is_product_category() can be used to change the displayed content based on the matched condition.
In this case you can use them to change the printed text based on category. You can exploit them in this way:
function woa_content_before_shop()
{
if ( is_product_category( 'shirts' ) )
{
echo "<p>Here are shirts!</p>";
}
else if ( is_product_category( 'games' ) )
{
echo "<p>Here are games!</p>";
}
else
{
...
}
}
add_action( 'woocommerce_before_shop_loop', 'woa_content_before_shop');
Use this code. Also set your descriptions in Products > Categories.
function woa_content_before_shop() {
if ( is_product_category() ) {
global $wp_query;
$id = $wp_query->get_queried_object_id();
$desc = term_description( $id, 'product_cat' );
if ( !empty( $desc ) ) {
$output = '<p>' . esc_html( $desc ) . '</p>';
echo $output;
}
}
}
add_action( 'woocommerce_before_shop_loop', 'woa_content_before_shop');

Multiple if Statements issue

I am having a problem with multiple if statements. I am using && but it seems to only work for the first statement.
The code is like such:
global $post;
$args = array( 'post_id' => $post->ID );
$comment = get_comments( $args );
$user = wp_get_current_user();
if ( 3 <= count( $comment ) && $post->post_author == $user->ID) {
echo do_shortcode( '[button]' );
} else {
comment_form();
}
It basically stats that if there is less than 3 comments then show the comment form but if there is more than 3 and is the post author then show a button. The button shows but only if there are more than 3 comments. It doesn't check if it is only the post author or not, like I want it to.
What you are describing are two cases in which the button should be showed. So there have to be two ways to get into the if-block. You have to refactor your if-statement with the logical or-operator ||.
for example:
if($post->post_author == $user->ID || 3 <= count($comment)) {
echo do_shortcode( '[button]' );
} else {
comment_form();
}
I had to change the code like so to get it to work.
global $post,$current_user;
$args = array( 'post_id' => $post->ID );
$comment = get_comments( $args );
get_currentuserinfo();
if ($post->post_author == $current_user->ID ) {
echo do_shortcode( '[button]' );
} elseif ( 3 <= count( $comment ) ) {
// blank
} else {
comment_form();
}

Categories