php - woocommerce expired products custom post_status -


i extended product post type of woocommerce have custom post_status called 'expired'.

the desired behavior publish product shop , set expired after time span.

only published products should visible in shop permalink product should still working after post_status set expired display different template.

woocommerce displays products(in shop , single product view) "publish" post_status default initial thought hook pre_get_posts , add 'expired' post_status query vars.

a little addition use same slug posts, products , pages.

http://example.com/page-name

http://example.com/post-name

http://example.com/product-name

to accomplish came following code:

add_action(     'pre_get_posts',     'custom_pre_get_posts' );  function custom_pre_get_posts($query) {     global $wpdb;      if( !is_admin() && $query->is_main_query() && $post_name = $query->get('name')) {          $result = $wpdb->get_row(             $wpdb->prepare(                 'select post_type, id, post_status '.$wpdb->posts.' post_name = %s limit 1',                 $post_name             )         );            if(!empty($result) && $result->post_type == 'product'){             $query->set('name', $post_name);             $query->set('product', $post_name);             $query->set('post_type', $result->post_type);             $query->set('post_status', $result->post_status);                        }       }  } 

just manually checking if post given name exists , post_status has. after query vars set accordingly.

and include custom template expired products:

add_filter(      'template_include',      'custom_expired_templates',      99  );  function custom_expired_templates($template){      global $wp_query;     $status = $wp_query->get('post_status');     $type = $wp_query->get('post_type');      if($status === 'expired' && $type ==='product'){         $template = locate_template( array( 'woocommerce/expired-single-product.php' ) );     }      return $template; } 

woocommerce/expired-single-product.php plain copy of woocmmerce/single-product.php in theme directory.

the above code works... seems kind of hacky way since custom template gets display wordpress sends 404 header , title gets set 'page not found' i'm overwriting 404-template.

a side effect woocommerce styles , scripts won't load. tried dig documentation of woocommerce not able isolate error.

any recommendations on proper way accomplish desired behavior?

update

verified resulting sql query adding

add_action('the_posts','test_sql_request');  function test_sql_request($posts){     echo $globals['wp_query']->request;     var_dump($posts);     return $posts; } 

the expired product has sql request:

select wp_posts.* wp_posts 1=1 , wp_posts.post_name = 'expired-product' , wp_posts.post_type = 'product' , ((wp_posts.post_status = 'expired')) order wp_posts.post_date desc 

but returns empty array. running exact query in phpmyadmin returned right post. query publish product looks identical except post_status , name (selfexplainatory) ... returns right post in array.

ok, failure not in code posted above in registration of post_status itself:

function my_custom_post_status(){      register_post_status( 'expired', array(         'label'                     => _x( 'expired', 'product' ),         'public'                    => false,         'exclude_from_search'       => true,         'show_in_admin_all_list'    => true,         'show_in_admin_status_list' => true,         'label_count'               => _n_noop( 'expired <span class="count">(%s)</span>', 'expired <span class="count">(%s)</span>' ),     ) ); }  add_action( 'init', 'my_custom_post_status' ); 

the problematic part is

 'public' => false 

and has changed to

'public' => true 

i didn't know public attribute affects querying when query id. expired product has id 103 , $post = new wp_query('p=103'); doesn't return single post $post = get_post(103); return correct post.

maybe prevents future headaches in similar situation.


Comments