I want to replace the product thumbnail based on stock. This works if I plop it directly into the wc-template-functions woocommerce_get_product_thumbnail function, but not when I try to hook into it from functions.php. This is my code:
function sold_out_thumb ($size = 'shop_catalog', $placeholder_width = 0, $placeholder_height = 0 ) {
global $product;
global $post;
if ( has_post_thumbnail() )
if ($product->price > 0 && !$product->is_in_stock() )
return get_the_post_thumbnail( $post->ID, $size,array( 'class' => 'lighter' ) );
else
return get_the_post_thumbnail( $post->ID, $size );
elseif ( wc_placeholder_img_src() )
return wc_placeholder_img( $size );
}
add_action ('woocommerce_get_product_thumbnail','sold_out_thumb',90);
Any ideas?
As you can see in wc-template-functions.php, almost all template functions are inside if ( !function_exists() ) condition. That way the creators of the plugin enabled us to override template functions, so just create woocommerce_get_product_thumbnail() function in functions.php, and the original will not be loaded.
There is no action called woocommerce_get_product_thumbnail which is why this isn't working for you. This is actually a function called woocommerce_get_product_thumbnail(). If you look at the code there is no action hook.
Related
I am using a function to add custom meta to products. I have used the following hooks for SHOW on Product Loop woocommerce_after_shop_loop_item and Product Single Page woocommerce_product_meta_end.
So, when applying to get the same results on CART PAGE product/item by using the hook
woocommerce_after_cart_item_name it doesn’t work with no results.
Why isn’t the hook woocommerce_after_cart_item_name working if it works with the other previous hooks mentioned?
This the code I am using. I just change the hook to make it to show in Product Loop and Product Single Page, need it to show on cart Products as well. I was just wondering why it doesn't work with cart item hook..
public function woocommerce_after_cart_item_name()
{
global $product;
if ( !PluginOptions::value('shop_season') && !PluginOptions::value('shop_car_type') )
return;
$product_id = $product->get_id();
$season = get_post_meta( $product_id, 'season', true );
$car_type = get_post_meta( $product_id, 'car_type', true );
$tips_seasons = $this->ui_tips_season();
$tips_car_types = $this->ui_tips_car_types();
?>
<div class="tyre-details tyre-tips">
<?php if ( PluginOptions::value('shop_season') && $season ): ?>
<?php echo $tips_seasons[ strtolower($season) ]; ?>
<?php endif ?>
<?php if ( PluginOptions::value('shop_car_type') && $car_type ): ?>
<?php echo $tips_car_types[ strtolower($car_type) ]; ?>
<?php endif ?>
</div>
<?php
}
It is from a plugin. I was just given this code from woocommerce support but i do not know how to complete it. He says to replace with my meta_keys in the code which I will post below here. Can you help me finish this? or tell me where I need to replace. My meta_keys are $season and $car-type but i don't know how to apply with the code provided by woocommerce.
// Display custom cart item meta data (in cart and checkout)
add_filter( 'woocommerce_get_item_data', 'display_cart_item_custom_meta_data', 10, 2 );
function display_cart_item_custom_meta_data( $item_data, $cart_item ) {
$meta_key = 'PR CODE';
if ( isset($cart_item['add_size']) && isset($cart_item['add_size'] [$meta_key]) ) {
$item_data[] = array(
'key' => $meta_key,
'value' => $cart_item['add_size'][$meta_key],
);
}
return $item_data;
}
// Save cart item custom meta as order item meta data and display it everywhere on orders and email notifications.
add_action( 'woocommerce_checkout_create_order_line_item', 'save_cart_item_custom_meta_as_order_item_meta', 10, 4 );
function save_cart_item_custom_meta_as_order_item_meta( $item, $cart_item_key, $values, $order ) {
$meta_key = 'PR CODE';
if ( isset($values['add_size']) && isset($values['add_size'][$meta_key]) ) {
$item->update_meta_data( $meta_key, $values['add_size'][$meta_key] );
}
}
I located the ClassName (class FeatureTyreTips) and added that to the code you provided. I entered this in functions.php and it said fatal error when loading the cart page. I also tried placing it in the cart.php with same results...and I tried in the same plugin file where this code came from originally. All 3 locations did not work...only difference was that it did not show fatal error when adding and activating your new code in the plugin file when loading cart page. Any ideas? grazie Vdgeatano
The "Fatal Error" is most likely due to the fact that "the non-static method cannot be called statically": PHP - Static methods
I have now corrected the code.
Considering that the class name that was missing in your code is FeatureTyreTips, the correct code to add some text after the product name is:
add_action( 'woocommerce_after_cart_item_name', 'add_custom_text_after_cart_item_name', 10, 2 );
function add_custom_text_after_cart_item_name( $cart_item, $cart_item_key ) {
// create an instance of the "PluginOptions" class
$PluginOptions = new PluginOptions();
if ( ! $PluginOptions->value( 'shop_season' ) && ! $PluginOptions->value( 'shop_car_type' ) ) {
return;
}
$product = $cart_item['data'];
$season = get_post_meta( $product->get_id(), 'season', true );
$car_type = get_post_meta( $product->get_id(), 'car_type', true );
// create an instance of the "FeatureTyreTips" class
$FeatureTyreTips = new FeatureTyreTips();
$tips_seasons = $FeatureTyreTips->ui_tips_season();
$tips_car_types = $FeatureTyreTips->ui_tips_car_types();
if ( ! $PluginOptions->value('shop_season') || ! $season ) {
$season = '';
}
if ( ! $PluginOptions->value('shop_car_type') || ! $car_type ) {
$car_type = '';
}
$html = '<div class="tyre-details tyre-tips">' . trim( $season . ' ' . $car_type ) . '</div>';
echo $html;
}
The code has been tested (where possible) and works.It needs to be added to your theme's functions.php file or in your plugin.
I am using this hook to run some code after the product is updated:
add_action( 'updated_post_meta', 'attach_variation_images_on_product_save', 10, 4 );
function attach_variation_images_on_product_save( $meta_id, $post_id, $meta_key, $meta_value ) {
if ( $meta_key == '_edit_lock' ) {
if ( get_post_type( $post_id ) == 'product' ) {
//do something
}
}
}
This is working as expected, the function is executed after the product is updated. I want to run the same function when a product is getting updated via the REST API. I hooked my function to woocommerce_rest_insert_product_object like this but it did not work:
add_action( 'woocommerce_rest_insert_product_object', 'attach_variation_images_on_product_update_via_rest', 10, 3 );
function attach_variation_images_on_product_update_via_rest( $post, $request, $true ) {
if ( get_post_type( $post ) == 'product' ) {
$product = wc_get_product( $post );
//do something
}
}
Am I not using the right hook? Is there another hook I can use?
EDIT 1: It seems that my code was not running because get_post_type($post) is type of post and not product. I am trying to attach an image to variations using add_post_meta($variation_id, '_thumbnail_id', $image_id); inside a loop. It seems the function attach_variation_images_on_product_update_via_rest( $post, $request, $true ) is executed till the end but it does not attach the image to the variations.
I ended up using this hook add_action( 'woocommerce_update_product', 'my_callback_function', 10, 1 ); that executes the callback function when you updating products from Woocommerce back-end as well from the REST API.
I was wondering if anyone knew how to set up a single template for multiple custom post types. For example - I don't want to set up multiple templates that do the exact same thing.
Code
I found the following snippet while searching and it doesn't seem to work. I have placed this in functions.php in the theme I am using.
add_filter( 'single_template', function( $template ) {
$cpt = [ 'available-properties', 'leased-sold', 'norway' ];
return in_array( get_queried_object()->post_type, $cpt, true )
? 'path/to/country-single.php'
: $template;
} );
Found the answer
This seems to work great!
add_filter( 'template_include', function( $template )
{
// your custom post types
$my_types = array( 'available-properties', 'leased-sold' );
$post_type = get_post_type();
if ( ! in_array( $post_type, $my_types ) )
return $template;
return get_stylesheet_directory() . '/page-content__projects-single.php';
});
<?php
function prfx_custom_meta()
{
add_meta_box(
'some_meta_box_name'
,__( 'Some Meta Box Headline', 'plugin_textdomain' )
,'render_meta_box_content' //this is callback function.
,'post_type'
,'advanced'
,'high'
);
}
add_action( 'add_meta_boxes', 'prfx_custom_meta' );
?>
I used the above code to create a metabox in Wordpress. But , for that
code it doesn't showing up
couldn't find the solution. kindly suggest any ideas for that problem
.
It all depends on where you want the metabox to appear.
If you want it to appear on posts then you need to use
if ( ! function_exists( 'add_post_metabox' ) ){
function add_post_metabox(){
add_meta_box('post-meta', esc_html__('My Metabox', 'mytheme'), 'My_Metabox_function', 'post', 'side', 'low');
}
}
add_action('admin_init', 'add_post_metabox');
And then create metabox with
if ( ! function_exists( 'My_Metabox_function' ) ){
function My_Metabox_function( $post ){
//metabox layout and variables here
}
}
if ( ! function_exists( 'My_Metabox_save_function' ) ){
function My_Metabox_save_function($post_id){
global $post;
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ){
return $post_id;
} else{
//do save here
}
}
}
add_action( 'save_post', 'My_Metabox_save_function' );
If you want it on page then you can create it like above but with page instead of post
if ( ! function_exists( 'add_page_metabox' ) ){
function add_page_metabox(){
add_meta_box('page-meta', esc_html__('My Metabox on Page', 'mytheme'), 'My_Metabox_page_function', 'page', 'normal', 'high');
}
}
add_action('add_meta_boxes', 'add_page_metabox');
You can hook to admin_init of add_meta_boxes hooks. See here for more explanation.
You can put it in your functions.php file or you can set it in separate .php file and call it in functions.php with something like:
require_once( get_template_directory(). '/include/metaboxes.php' );
This will include metaboxes.php that are located in the /include directory of your theme.
I have a website with some custom post type created with Ultimate CMS plugin.
In admin area, when I make a new search, the result is ok, but after that, when I'm try to make a second search, It give me an error "Invalid post type".
I also realize that the url it's not ok:
In the first search, the url is something like this:
http://www.site.com/wp-admin/edit.php?s=SearchTerm1&post_status=all&post_type=post&action=-1&m=0&cat=0&paged=1&mode=list&action2=-1
In the second search, the url is something like:
http://www.site.com/wp-admin/edit.php?s=SearchTerm2&post_status=all&post_type=Array&_wpnonce=4d88f268e4&_wp_http_referer=%2Fwp-admin%2Fedit.php%3Fs%3DSearchTerm1%26post_status%3Dall%26post_type%3Dpost%26action%3D-1%26m%3D0%26cat%3D0%26paged%3D1%26mode%3Dlist%26action2%3D-1&action=-1&m=0&cat=0&paged=1&mode=list&action2=-1
And the error message: "Invalid post type".
I deactived all of my plugins, I upgraded wordpress to the latest version 3.5.1, I reset permalinks to default, but this error still remain.
Any help would be much appreciated!
Thank you
I also came across this issue and found that it was a result of one of my functions in my functions.php file that was modifying the global wordpress query parameters.
It sounds like you edited the global $query object. If you used a hook such as 'pre_get_posts' and manipulated the $query object and you do not exclude the admin area, then any changes you make to the query parameters will also apply to the admin panel and it will display that error when trying to add in parameters that don't fit your search.
For example:
Let's say you have a search feature on your site, and when the user enters a search and goes to the search results page, you only want to display posts of a custom post type called $searchable_posts, then you would add a hook to your functions.php file like this:
function searchfilter($query) {
if ($query->is_search && $query->is_main_query() ) {
$query->set('post_type', $searchable_posts);
}
return $query;
}
add_filter('pre_get_posts', 'searchfilter');
This will make it so that any global default $query will only search for results that have a matching post type of $searchable_posts. However, the way it is written above means this will also apply to any global $query in the admin panel also.
The way around this is to structure your query like this:
function searchfilter($query) {
if ($query->is_search && $query->is_main_query() && !is_admin() ) {
$query->set('post_type', $searchable_posts);
}
return $query;
}
add_filter('pre_get_posts', 'searchfilter');
Adding in that !is_admin() means that your function will exclude anything in the backend administration panel (see is_admin ).
Alternatively, a safer way if you can, instead of using the global default $query is to create your own new WP_Query and searching using that instead - the codex has good examples of how to set that up.
I am also get the issue same as you and finally I got the solution.
We have to add $query->is_main_query() in IF CONDITION.
Below is the full code.
function acf_meta_value_filter() {
global $typenow;
global $wp_query;
if ( $typenow == 'your_custom_post_type_name' ) { // Your custom post type meta_key_name
$plugins = array( 'value1', 'value2', 'value3' ); // Options for the filter select field
$current_plugin = '';
if( isset( $_GET['meta_key_name'] ) ) {
$current_plugin = $_GET['meta_key_name']; // Check if option has been selected
} ?>
<select name="meta_key_name" id="meta_key_name">
<option value="all" <?php selected( 'all', $current_plugin ); ?>><?php _e( 'All', '' ); ?></option>
<?php foreach( $plugins as $key=>$value ) { ?>
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, $current_plugin ); ?>><?php echo esc_attr( $value ); ?></option>
<?php } ?>
</select>
<?php }
}
add_action( 'restrict_manage_posts', 'acf_meta_value_filter' );
function acf_meta_value_filter_by_slug( $query ) {
global $pagenow;
// Get the post type
$post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : '';
if ( is_admin() && $pagenow=='edit.php' && $post_type == 'your_custom_post_type_name' && isset( $_GET['meta_key_name'] ) && $_GET['meta_key_name'] !='all' && $query->is_main_query()) {
$query->query_vars['meta_key'] = 'meta_key_name';
$query->query_vars['meta_value'] = $_GET['meta_key_name'];
$query->query_vars['meta_compare'] = '=';
}
}
add_filter( 'parse_query', 'acf_meta_value_filter_by_slug' );
I had a similar problem with a site a took over from other dev.
function anty_search_form( $query ) {
if ( $query->is_search ) {
$query->set( 'post_type', array('post', 'product') );
}
return $query;
}
add_filter( 'pre_get_posts', 'anty_search_form' );
Someone forgot to exclude this function from wp-admin page. So changing to this helped Invalid post type.
function anty_search_form( $query ) {
if (!is_admin()){
if ( $query->is_search ) {
$query->set( 'post_type', array('post', 'product') );
}
return $query;
}
}
add_filter( 'pre_get_posts', 'anty_search_form' );
At wp-admin when submitted the second search for a custom post type, I was getting the same error, "Invalid post type." The URL seemed long and incorrect. Anyway, the following code worked perfectly:
add_filter( 'pre_get_posts', 'tgm_io_cpt_search' );
function tgm_io_cpt_search( $query ) {
if ( $query->is_search ) {
$query->set( 'post_type', 'your_custom_post_type' );
}
return $query;
}