Woocommerce / sort related products by price - sorting

I added this filter to functions.php, but unfortunately it doesn't work. May anybody please help to find the reason
add_filter( 'woocommerce_grouped_children_args', 'custom_grouped_children_args', 18 );
function custom_grouped_children_args( $args ){
$args = array(
'post_type' => 'product',
'posts_per_page' => 4,
'orderby' => 'meta_value_num',
'meta_key' => '_price',
'order' => 'desc'
);
}

just found out the solution, in case anybody needs it. I just had to remove the default filter and then to add mine
function custom_remove_hook(){
remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20 );
add_action( 'woocommerce_after_single_product_summary', 'custom_function_to_sort_related', 22 );
}
add_action( 'woocommerce_after_single_product_summary', 'custom_remove_hook' );
function custom_function_to_sort_related( $args = array() ) {
global $product;
if ( ! $product ) {
return;
}
$defaults = array(
'posts_per_page' => 4,
'columns' => 4,
'orderby' => 'price', // #codingStandardsIgnoreLine.
'order' => 'desc'
);
$args = wp_parse_args( $args, $defaults );
// Get visible related products then sort them at random.
$args['related_products'] = array_filter( array_map( 'wc_get_product', wc_get_related_products( $product->get_id(), $args['posts_per_page'], $product->get_upsell_ids() ) ), 'wc_products_array_filter_visible' );
// Handle orderby.
$args['related_products'] = wc_products_array_orderby( $args['related_products'], $args['orderby'], $args['order'] );
// Set global loop values.
wc_set_loop_prop( 'name', 'related' );
wc_set_loop_prop( 'columns', apply_filters( 'woocommerce_related_products_columns', $args['columns'] ) );
wc_get_template( 'single-product/related.php', $args );
}

Related

Wordpress Lazy Loading using Pagination

im doing a lazy loading with WP_Query Pagination
it's working fine but the content duplicate itself when it reaches it's end
and when i search for a specific result it shows the result correctly
but after that it still want to do lazy load so it load random data
here is my code
lazy-load.php
<?php
add_action('wp_ajax_nopriv_load_posts_by_ajax', 'load_posts_by_ajax_callback');
add_action('wp_ajax_load_posts_by_ajax', 'load_posts_by_ajax_callback');
function load_posts_by_ajax_callback(){
// check_ajax_referer( 'load_more_posts', 'security' );
$paged = $_POST['page'];
$args = array(
'post_type' => 'unit',
'post_status' => 'publish',
'posts_per_page' => 4,
'paged' => $paged
);
if ( !empty($_POST['taxonomy']) && !empty($_POST['term_id']) ){
$args['tax_query'] = array (
array(
'taxonomy' => $_POST['taxonomy'],
'terms' => $_POST['term_id'],
),
);
}
if ( ! is_null($_POST['offer']) ) {
$args['meta_query'][] = array(
'key' => 'WAKEB_hot',
'value' => '1',
'compare' => '=',
);
}
if ( ! is_null($_POST['purpose']) ) {
$args['meta_query'][] = array(
'key' => 'WAKEB_vacation',
'value' => '1',
'compare' => '=',
);
}
if (!empty($_POST['project'])){
$args['meta_query'] = array (
array(
'key' => 'WAKEB_project',
'value' => $_POST['project'],
'compare' => '='
),
);
}
// start buffer
ob_start();
$query = new WP_Query( $args );
if ( $query->have_posts() ) :
while($query->have_posts()){ $query->the_post();
get_template_part("template-parts/units");
}
endif; wp_reset_postdata();
// start buffered data in data variable
$data = ob_get_clean();
wp_send_json_success( $data );
wp_die();
}
add_action('wp_ajax_nopriv_load_projects_by_ajax', 'load_projects_by_ajax_callback');
add_action('wp_ajax_load_projects_by_ajax', 'load_projects_by_ajax_callback');
function load_projects_by_ajax_callback(){
// check_ajax_referer( 'load_more_posts', 'security' );
$paged = $_POST['page'];
$args = array(
'post_type' => 'project',
'post_status' => 'publish',
'posts_per_page' => 4,
'paged' => $paged
);
if ( ! is_null($_POST['ptype']) ) {
$args['tax_query'] = array (
array(
'taxonomy' => 'pptypes',
'field' => 'slug',
'terms' => $_POST['ptype'],
),
);
}
if ( !empty($_POST['taxonomy']) && !empty($_POST['term_id']) ){
$args['tax_query'] = array (
array(
'taxonomy' => $_POST['taxonomy'],
'terms' => $_POST['term_id'],
),
);
}
// start buffer
ob_start();
$query = new WP_Query( $args );
if ( $query->have_posts() ) :
while($query->have_posts()){ $query->the_post();
get_template_part("template-parts/projects");
}
endif; wp_reset_postdata();
// start buffered data in data variable
$data = ob_get_clean();
wp_send_json_success( $data );
wp_die();
}
lazy-load.js
$('.unit-terms li a').each( function() {
if ( this.href == window.location.href ) {
$(this).parent().addClass('current');
}
});
main.js
(function($){
$('.isotope a').on('click', function(){
$('.isotope .active').removeClass('active');
$(this).addClass('active');
var filter = $(this).data('filter');
if(filter=='*'){
$('.property').show();
}else{
$('.property').not(filter).hide();
$('.property'+filter).show();
}
return false;
});
})(jQuery);
so how can i make it work? i don't know what im doing wrong here
Here is the repo link for the full project
https://github.com/Ov3rControl/hoomerz
ok, now I understand what you meant ;) During lazy load you send to backend only page number without current state of filters and / or search string. So it sends all posttype items based on page number only. You should send also current state of filters
main.js: add this to your after-page-load function:
var currentUrl = new URL(window.location.href);
var searchQuery = urlObj.searchParams.get("k");
lazy-load.js: add search param to data posted to backend
var data = {
'action': 'load_posts_by_ajax',
'page': page,
'search: searchQuery // new field
};
lazy-load.php: add search param to WP_Query
if ( isset($_POST['search']) && !empty($_POST['search']) ){ // new section
$args['s'] = sanitize_text_field($_POST['search']);
}
That's example for text search filter. For all filters you must
1. match every filter from front (URL get param) (main.js)
2. than put it in data object sent to backend (lazy-load.js)
3. address this variable in lazy-load.php in if(isset($_POST['param-name'])) section ( new or existing one as there are some )
I suggest to try without ob_start() / ob_get_clean(). Also if you generate html instead of raw data structure, I would simply print it to output without wp_send_json_success().
Other solution would be sending raw data (1. array in php, 2. json_encode(), 3. wp_send_json() ) and than processing in javascript (dynamic dom element creation after request to backend made).

Trash realated post by custom field value in multisite

I have a multisite setup were the custom post type article has a relation to other posts at the network by the custom field alphanumeric_id This key is unique on each blog and the related posts are generated programmatically on add_action('wp_insert_post', 'bZive_create_TranslatedContent', 15, 3);
function bZive_trash_TranslatedContent($post_id){
// Get the current blog id
$original_site_id = get_current_blog_id();
$postTypes = array('profile', 'article');
$postType = get_post_type( get_the_ID() );
$randomString = get_post_meta( get_the_ID(), 'alphanumeric_id', true );
$args = array(
'public' => true,
'limit' => 500
);
$sites = wp_get_sites($args);
$tests = array();
foreach ($sites as $site) {
switch_to_blog($site['blog_id']);
if( get_current_blog_id() != $original_site_id and get_current_blog_id() != 1 ){
$args = array(
'post_type' => 'article',
'post_status' => array(
'publish', 'draft', 'pending','auto-draft', 'future', 'private'
),
'meta_query' => array(
array(
'key' => 'alphanumeric_id',
'value' => $randomString ,
'compare' => '=',
),
),
);
$posts = new WP_Query($args);
if( $posts->have_posts() ) {
while( $posts->have_posts() ) {
$posts->the_post();
// Move the post to trash
wp_trash_post(get_the_ID());
}
}
wp_reset_postdata();
}
restore_current_blog();
}
}
add_action('trash_post','bZive_trash_TranslatedContent',10,3);
What I want to archive: If I move one post to the trash - all related post should be moved to the trash too. But somehow the posts aren't getting deleted - I tested the WP_Query it's getting the right posts but still, they don't get deleted.
Finally working!
function bZive_trash_TranslatedContent($post_id){
// Get the current blog id
$original_site_id = get_current_blog_id();
$postTypes = array('profile', 'article');
$postType = get_post_type( get_the_ID() );
$randomString = get_post_meta( get_the_ID(), 'alphanumeric_id', true );
if (in_array( $postType, $postTypes ) and empty( get_post_meta( $post_id, 'del_translatedContent', true ) ) ) {
add_post_meta($post_id, 'del_translatedContent', 'true');
$args = array(
'public' => true,
'limit' => 500
);
$sites = wp_get_sites($args);
$tests = array();
foreach ($sites as $site) {
switch_to_blog($site['blog_id']);
if( get_current_blog_id() != $original_site_id and get_current_blog_id() != 1 ){
$args = array(
'post_type' => 'article',
'post_status' => array(
'publish', 'draft', 'pending','auto-draft', 'future', 'private'
),
'meta_query' => array(
array(
'key' => 'alphanumeric_id',
'value' => $randomString ,
'compare' => '=',
),
),
);
$posts = new WP_Query($args);
if( $posts->have_posts() ) {
while( $posts->have_posts() ) {
$posts->the_post();
// Move the post to trash
wp_trash_post(get_the_ID());
add_post_meta(get_the_ID(), 'del_translatedContent', 'true');
}
}
wp_reset_postdata();
}
restore_current_blog();
}
}
}
add_action('wp_trash_post','bZive_trash_TranslatedContent',1,3);

drupal custom views filter

First time on stackoverflow so , i will try to be as clear as possible.
I'm using drupal 7 and views 3.
I needed to create a custom views filter that handle dates range. So i looked at example and tried to mimic the behavior and i get some trouble.
It seems that when i extend my own class from views_handler_filter , the query method is never invoked BUT if i extend my class from let's say views_handler_filter_string, it works oO...
I must forget something but i'm stuck here ...
Here is my code, if someone can take a look and advise me about what happend , i would be very grateful.
Thanks everyone !
Here is my .views.inc file :
<?php
class v3d_date_custom_filter extends views_handler_filter {
var $always_multiple = TRUE;
function value_form(&$form, &$form_state) {
//parent::value_form($form, $form_state);
$form['value']['v3d_date']['period'] = array(
'#type' => 'select',
'#title' => 'Period',
'#options' => array(
'7_days' => 'Last 7 days',
'yesterday' => 'Yesterday',
'today' => 'Today',
'custom' => 'Custom dates'),
'#default_value' => 'custom',
'#attributes' => array("onclick" => "period_click(this);"),
);
$form['value']['v3d_date']['start_date'] = array(
'#type' => 'date_popup',
'#date_format' => 'Y-m-d',
'#title' => 'Start date',
'#size' => 30);
$form['value']['v3d_date']['end_date'] = array(
'#type' => date_popup',
'#title' => 'End date',
'#date_format' => 'Y-m-d',
'#size' => 30);
}
function exposed_validate(&$form, &$form_state) {
if(is_null($form_state['values']['start_date']) &&
is_null($form_state['values']['start_date'])) {
return TRUE;
}
/*
* If we get array for start_date or end_date
* errors occured, but the date module will handle it.
*/
if(!is_string($form_state['values']['start_date']) ||
!is_string($form_state['values']['end_date'])) {
return TRUE;
}
/* Get day, month and year from start_date string */
if(!preg_match('/(\d+)-(\d+)-(\d+)/',
$form_state['values']['start_date'],
$start_date
)) {
return TRUE; }
/* Get day, month and year from end_date string */
if(!preg_match('/(\d+)-(\d+)-(\d+)/',
$form_state['values']['end_date'],
$end_date
)) {
return TRUE; }
/* Create timestamps and compare */
$start_date = mktime(0,0,0,$start_date[1],$start_date[2],$start_date[3]);
$end_date = mktime(0,0,0,$end_date[1],$end_date[2],$end_date[3]);
if($start_date >= $end_date) {
form_set_error('start_date','Start date must be anterior to end date.');
}
}
function query() {
die('fdsfds');
$this->ensure_my_table();
$field = "$this->table_alias.$this->real_field";
dsm($this);
}
}
?>
And my .module file
<?php
function custom_filters_views_api() {
return array(
'api'=>3,
'path' => drupal_get_path('module','custom_filters') . '/views',
);
}
?>
And part of my views_data that use my custom filter :
<?php
function voice_views_data() {
$data['v_tp_voice']['date_utc_agent'] = array(
'title' => t('date_utc_agent'),
'help' => 'date_utc_agent',
'field' => array('handler' => 'views_handler_field'),
'filter' => array('handler' => 'v3d_date_custom_filter'),
'sort' => array('handler' => 'views_handler_sort')
);
I am working on this same problem. My setup looks very much like yours, though I do call parent::value_form($form, $form_state) in my value_form function.
I found that in the value_form function, I had to have something like
$form['value'] = array(
'#type' => 'checkbox',
'#title' => "Filter by Date",
'#default_value' => $this->value,
);
in order to have my query() function called. Doing something like $form['value']['before'] = array( ...
didn't work.

WooCommerce Custom Loop to get all product from one specific category

I try to find the code (short code) in the woo comm plugin that made the list of all the product from one category, to be able to modify it... no luck after 1 hours, still no find.
So i start coding it myself (reinventing the wheel) and here what i try to get
get me all the product from category ID="151" and be able to output the name, the permalink etc etc...
this is the code now, that return everything.... way too much ! and i don't know how to filter it
{
$args = array(
'post_type' => 'product',
'posts_per_page' => 99
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
//echo get_title()."<br/>";
var_dump($loop);
endwhile;
}
here is the code i have found, and modify to my needs
function get_me_list_of($atts, $content = null)
{
$args = array( 'post_type' => 'product', 'posts_per_page' => 10, 'product_cat' => $atts[0], 'orderby' => 'rand' );
$loop = new WP_Query( $args );
echo '<h1 class="upp">Style '.$atts[0].'</h1>';
echo "<ul class='mylisting'>";
while ( $loop->have_posts() ) : $loop->the_post();
global $product;
echo '<li>'.get_the_post_thumbnail($loop->post->ID, 'thumbnail').'</li>';
endwhile;
echo "</ul>";
wp_reset_query();
}
?>
The [product_category] shortcode defined in /woocommerce/includes/class-wc-shortcodes.php is a great starting place for this, particularly as Woocommerce is constantly evolving!
The guts of it is just a standard WP_Query with some extra code added on to do pagination, setting sort orders from the Woocommerce settings and some checking to see if the products are marked as visible or not.
So if you strip out the shortcode related code and wanted a function that just got visible products from a category with a specific slug, it would look like this:
function getCategoryProducts($category_slug) {
// Default Woocommerce ordering args
$ordering_args = WC()->query->get_catalog_ordering_args();
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'orderby' => $ordering_args['orderby'],
'order' => $ordering_args['order'],
'posts_per_page' => '12',
'meta_query' => array(
array(
'key' => '_visibility',
'value' => array('catalog', 'visible'),
'compare' => 'IN'
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'terms' => array( esc_attr( $category_slug ) ),
'field' => 'slug',
'operator' => 'IN' // Possible values are 'IN', 'NOT IN', 'AND'.
)
)
);
if ( isset( $ordering_args['meta_key'] ) ) {
$args['meta_key'] = $ordering_args['meta_key'];
}
$products = new WP_Query($args);
woocommerce_reset_loop();
wp_reset_postdata();
return $products;
}
Pass in the slug and you'll get back a standard wordpress posts collection using the same ordering that you've configured in your Woocommerce settings.
I had similar problem as I wanted to get "Fabrics" product for a "Custom Page", here is the code I used.
<ul class="products">
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => 12,
'product_cat' => 'fabrics'
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
woocommerce_get_template_part( 'content', 'product' );
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
?>
</ul><!--/.products-->
Using the above code means you get the default inline styles, classes and other necessary tags.

output child terms of current custom taxonomy term with images

Just wondering if anyone can help with this - banging my head for days...
From a custom taxonomy page (taxonomy_genre.php), I need to output the child terms with images.
I'm using the 'Taxonomy Images' plugin to set the image.
Code below - thanks in advance if anyone can give me some pointers!
code #1 outputs all terms including parent terms.
code #2 outputs the correct terms but with no images
essentially I'm trying to amalgamate the two.
code #1:
$current_term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) );
$args = array(
'taxonomy' => $current_term->taxonomy,
'child_of' => $current_term->term_id,
'term_args' => array(
'orderby' => 'id',
'order' => 'ASC',
'hierarchical' => 0,
),
);
$cats = apply_filters( 'taxonomy-images-get-terms', '', $args );
foreach ($cats as $cat) {
echo '<li><a href="' . get_category_link($cat) . '" title="'. $cat->name .'">' ;
echo wp_get_attachment_image( $cat->image_id, 'detail' );
echo $cat->name ;
echo '</a></li>';
}
code #2
$current_term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) );
$cats = wp_list_categories( array(
'child_of' => $current_term->term_id,
'taxonomy' => $current_term->taxonomy,
'hide_empty' => 0,
'hierarchical' => false,
'depth' => 2,
'title_li' => ''
));
foreach ((array)$cats as $cat) {
$catdesc = $cat->category_description;
echo '<li>'. wp_get_attachment_image( $cat->image_id, 'detail' ) . $cat->cat_name . '</li>'; }
Sorted - used:
'parent' => $current_term->term_id,
instead of:
child_of => $current_term->term_id,

Resources