Overriding WooCommerce function in includes folder - php

I am looking to make some modifications to a function in WooCommerce, on a file called class-wc-product-variation.php in woocommerce/includes/
The function I'm looking to modify is:
public function variation_is_visible() {
$visible = true;
// Published == enabled checkbox
if ( get_post_status( $this->variation_id ) != 'publish' ) {
$visible = false;
}
// Out of stock visibility
elseif ( get_option('woocommerce_hide_out_of_stock_items') == 'yes' && ! $this->is_in_stock() ) {
$visible = false;
}
// Price not set
elseif ( $this->get_price() === "" ) {
$visible = false;
}
return apply_filters( 'woocommerce_variation_is_visible', $visible, $this->variation_id, $this->id );
}
I need to add another elseif line in there like so:
elseif ( get_option('woocommerce_hide_out_of_stock_items') != 'yes' && ! $this->is_in_stock() ) {
$visible = false;
}
How do I do this without making changes to the core files?

You should never modify the core files in plugin. In the given function, there is filter woocommerce_variation_is_visible available. Use that filter to customize as per your need.
Code in core file is:
return apply_filters( 'woocommerce_variation_is_visible', $visible, $this->variation_id, $this->id );

Related

php add 2 or more post_type in $query

code original
if ( 'property' != $post->post_type ) {
return $query;
}
what i want to do but it doesn't work like that
if ( 'property' != $post->post_type ) {
if ( 'testimonial' != $post->post_type ) {
return $query;
}
How to add 2 or 3 post types ?
I add the full code so you can maybe understand why it doesn't work
and figure out how to make it work for different post types
add_filter( 'ajax_query_attachments_args', 'filter_query_attachments_args' );
function filter_query_attachments_args( $query ) {
// 1. Only users with access
if ( ! current_user_can( 'upload_files' ) ) {
wp_send_json_error();
}
// 2. No manipulation for admins.
// After all they have access to all images.
//if ( current_user_can( 'administrator' ) ) {
//return $query;
//}
// 3. No images, if the post_id is not provided
if ( ! isset( $_REQUEST['post_id'] ) ) {
wp_send_json_error();
}
// 4. No images, if you are not the post type manager or author
$post = get_post( (int) $_REQUEST['post_id'] );
if ( ! $post instanceof \WP_Post ) {
return $query;
}
// 5. You can also restrict the changes to your custom post type
// Only filter for our custom post types
if ( 'property' != $post->post_type ) {
return $query;
}
// 5. You can also restrict the changes to your custom post type
if ( 'testimonial' != $post->post_type ) {
return $query;
}
// 8. Don't show private images
$query['post_status'] = 'inherit';
// 9. Filter to display only the images attached to the post
$query['post_parent'] = $post->ID;
// 10. Filter to display only the user uploaded image
$query['editor'] = $current_user->ID;
return $query;
}
If I understand what you are asking, you want to be able to check two separate variables from the contents of post. You can put them in the same if block like this:
if ( 'property' != $post->post_type && 'testimonial' != $post->post_type ) {
return $query;
}
The two equality comparisons need to be separated by a logical && operator.
Alternatively, you could nest the if blocks like this:
if ( 'property' != $post->post_type) {
if ('testimonial' != $post->post_type ) {
return $query;
}
}
Depending on your implementation, you may want to use !== instead of != to check not only for the value but also the type. See https://www.php.net/manual/en/language.operators.comparison.php
for more information about operators in PHP.
You can use in_array
if (in_array($post->post_type, ['property', 'testimonial'])) {}

How to remove Warning: Attempt to read property "post_name"

i have shop on wordpress/woocommerce. When I added function to have sold out products at the end of list I'm getting warnings:
Warning: Attempt to read property "ID" on null in .../ftp/wp/wp-includes/class-wp-query.php on line 4044
Warning: Attempt to read property "post_title" on null in .../ftp/wp/wp-includes/class-wp-query.php on line 4046
Warning: Attempt to read property "post_name" on null in .../ftp/wp/wp-includes/class-wp-query.php on line 4048
Warning: Attempt to read property "post_type" on null in .../ftp/wp/wp-includes/class-wp-query.php on line 4196
Warning: Undefined array key 0 in .../ftp/wp/wp-includes/capabilities.php on line 76
lines from 4031 to 4064:
public function is_page( $page = '' ) {
if ( ! $this->is_page ) {
return false;
}
if ( empty( $page ) ) {
return true;
}
$page_obj = $this->get_queried_object();
$page = array_map( 'strval', (array) $page );
if ( in_array( (string) $page_obj->ID, $page, true ) ) {
return true;
} elseif ( in_array( $page_obj->post_title, $page, true ) ) {
return true;
} elseif ( in_array( $page_obj->post_name, $page, true ) ) {
return true;
} else {
foreach ( $page as $pagepath ) {
if ( ! strpos( $pagepath, '/' ) ) {
continue;
}
$pagepath_obj = get_page_by_path( $pagepath );
if ( $pagepath_obj && ( $pagepath_obj->ID == $page_obj->ID ) ) {
return true;
}
}
}
return false;
}
code for sorting products:
/**
* Sorting out of stock WooCommerce products - Order product collections by stock status, in-stock products first.
*/
class iWC_Orderby_Stock_Status
{
public function __construct()
{
// Check if WooCommerce is active
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
add_filter('posts_clauses', array($this, 'order_by_stock_status'), 2000);
}
}
public function order_by_stock_status($posts_clauses)
{
global $wpdb;
// only change query on WooCommerce loops
if (is_woocommerce() && (is_shop() || is_product_category() || is_product_tag())) {
$posts_clauses['join'] .= " INNER JOIN $wpdb->postmeta istockstatus ON ($wpdb->posts.ID = istockstatus.post_id) ";
$posts_clauses['orderby'] = " istockstatus.meta_value ASC, " . $posts_clauses['orderby'];
$posts_clauses['where'] = " AND istockstatus.meta_key = '_stock_status' AND istockstatus.meta_value <> '' " . $posts_clauses['where'];
}
return $posts_clauses;
}
}
new iWC_Orderby_Stock_Status;
/**
* END - Order product collections by stock status, instock products first.
*/
when i removed those code i don't get warnings.
Any ideas how to remove those warnings?
my shop: customoweplugi.pl
If you do not know what impact the changes you have made may have on the code and you don't understand it at least to the point that you are confident that those changes won't mess anything, then don't make those changes in the first place!
I do not recommend it, but if you just don't want to see this warnings then you can use an "Error Control Operator". Just add "#" before your expression like:
#$page_obj->ID
IT WONT SOLVE THE ERRORS, but will only prevent them from displaying!
Read more about Error Control Operators here:
https://www.php.net/manual/en/language.operators.errorcontrol.php

Set a custom user role based on registration email in WooCommerce

I added a custom filter to my functions.php file. When I first loaded it up which was a few versions of Woocommerce ago it worked perfectly.
Now it seems that all users are registered as the default 'customer' as opposed to 'student' when their emails do contain .ac.uk or .sch.uk
The filter function is as follows:
add_filter( 'woocommerce_new_customer_data', 'student_role', 10, 1 );
function student_role( $new_cust_data ) {
if ( strpos($new_cust_data['user_email'], '.ac.uk' ) >= 1 ) {
$new_cust_data['role'] = 'student';
}
elseif ( strpos($new_cust_data['user_email'], '.sch.uk') >= 1 ) {
$new_cust_data['role'] = 'student';
}
else {
$new_cust_data['role'] = 'customer';
}
return $new_cust_data;
}
Any help?
Try to replace >= 1 with !== false in your code (also it can be simplified) as follows:
add_filter( 'woocommerce_new_customer_data', 'set_new_customer_user_role_conditionaly' );
function set_new_customer_user_role_conditionaly( $args ) {
if ( strpos($args['user_email'], '.ac.uk') !== false || strpos($args['user_email'], '.sch.uk') !== false ){
$args['role'] = 'student';
}
return $args;
}
It should work.

Add wordpress filter for a custom field to add a dynamic value

I would like to add a dynamic value to a custom field in wordpress.
I do not want to use update_post_meta() because it is a dynamic value that I want to add every time when the post is loaded ..
The custom field is tm_video_file, and retrieved with get_post_meta().
This will return a URL, I beed to append a query string to it.
I am trying to hook a function that will change the value of "tm_video_file", but without success.
// URL will be called as:
get_post_meta($post_id, 'tm_video_file', true);
// I try to add a filter for these meta data
add_filter('get_post_metadata', array($this,'add_hash_key'),1,4);
// And try to append the tm_video_file value here:
public function add_hash_key ($meta_value, $post_id, $meta_key, $single ) {
if($meta_key == 'tm_video_file') {
var_dump($meta_value); // ALWAYS NULL ???
var_dump($post_id);
var_dump($meta_key);
var_dump($single);
}
return $meta_value.'?hash=something-dynamic-here';
}
UPDATE:
I have found out some information on the net, and I think I am a bit closer to the solution:
public static function add_hash_key($meta_value, $object_id, $meta_key, $single) {
if ($meta_key == 'tm_video_file') {
$meta_type = 'post';
$meta_cache = wp_cache_get($object_id, $meta_type . '_meta');
if ( !$meta_cache ) {
$meta_cache = update_meta_cache( $meta_type, array( $object_id ) );
$meta_cache = $meta_cache[$object_id];
}
if ( isset($meta_cache[$meta_key]) ) {
if ( $single ) {
$meta_value = maybe_unserialize( $meta_cache[$meta_key][0] );
} else {
$meta_value = array_map('maybe_unserialize', $meta_cache[$meta_key]);
}
}
// At this point $meta_value contains the right data!
$meta_value .= '?Hash-Here';
return array($meta_value); //
}
}
In wordpress file meta.php there is a function called:
get_metadata()
This will apply filters, and returns the value in the end:
$check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single );
if ( null !== $check ) {
if ( $single && is_array( $check ) )
return $check[0];
else
return $check;
}
//For some reason $check is ALWAYS null .. ? But the filter function did run for sure..

Pass User Id through Shortcode

I'll preface my questions by saying I am certainly not a programmer... but I am trying to build a membership site and would like to display the following function/shortcode I have by user id on their profile page. This shortcode currently shows all information not specific to a user and the membership plugin I am using uses the base WP user id. Any insight on how I can pass the ID through the shortcode?
function view_events_by_user($args, $format='', $user_id)
{
$args = (array) $args;
$args['ajax'] = isset($args['ajax']) ? $args['ajax']:(!defined('EM_AJAX') || EM_AJAX );
$args['format'] = ($format != '' || empty($args['format'])) ? $format : $args['format'];
$args['format'] = html_entity_decode($args['format']); //shortcode doesn't accept html
$args['limit'] = isset($args['limit']) ? $args['limit'] : get_option('dbem_events_default_limit');
if( empty($args['format']) && empty($args['format_header']) && empty($args['format_footer']) ){
ob_start();
if( !empty($args['ajax']) ){ echo '<div class="em-search-ajax">'; } //open AJAX wrapper
em_locate_template('templates/events-list.php', true, array('args'=>$args));
if( !empty($args['ajax']) ) echo "</div>"; //close AJAX wrapper
$return = ob_get_clean();
}else{
$args['ajax'] = false;
$pno = ( !empty($args['pagination']) && !empty($_GET['pno']) && is_numeric($_GET['pno']) )? $_GET['pno'] : 1;
$args['page'] = ( !empty($args['pagination']) && !empty($args['page']) && is_numeric($args['page']) )? $args['page'] : $pno;
$return = EM_Events::output( $args );
}
return $return;
}
add_shortcode ( 'view_events', 'view_events_by_user');

Categories