gpt4 book ai didi

php - woocommerce 过期产品自定义 post_status

转载 作者:可可西里 更新时间:2023-11-01 00:59:31 25 4
gpt4 key购买 nike

我扩展了 woocommerce 的产品帖子类型,使其具有一个名为“expired”的自定义 post_status

期望的行为是将产品发布到商店并将其设置为在特定时间跨度后过期。

只有已发布的产品应该在商店中可见,但在 post_status 设置为过期后产品的永久链接应该仍然有效,但显示不同的模板。

默认情况下,Woocommerce 本身仅显示带有“发布”post_status 的产品(在商店和单一产品 View 中),所以我最初的想法是简单地连接到 pre_get_posts 和将“expired”添加到 post_status 查询变量。

一点补充是对帖子、产品和页面使用相同的 slug。

http://example.com/page-name

http://example.com/post-name

http://example.com/product-name

为了完成这一切,我想出了以下代码:

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 FROM '.$wpdb->posts.' WHERE 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);
}


}

}

只是手动检查具有给定名称的帖子是否存在以及它的 post_status 是什么。之后,相应地设置查询变量。

并包含过期产品的自定义模板:

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 只是我主题目录中 woocmmerce/single-product.php 的普通副本。

上面的代码有效...但是这样做似乎有点老套,因为自定义模板得到了显示,但是 wordpress 发送了一个 404 header 并且标题被设置为“找不到页面”,所以我基本上是覆盖了404 模板。

副作用是 woocommerce 样式和脚本不会加载。我真的试图深入研究 woocommerce 的文档,但我无法找出错误。

关于实现所需行为的正确方法有什么建议吗?

更新

通过添加验证生成的 SQL 查询

add_action('the_posts','test_sql_request');

function test_sql_request($posts){
echo $GLOBALS['wp_query']->request;
var_dump($posts);
return $posts;
}

过期产品有SQL请求:

SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_name = 'expired-product' AND wp_posts.post_type = 'product' AND ((wp_posts.post_status = 'expired')) ORDER BY wp_posts.post_date DESC

但它返回一个空数组。在 phpmyadmin 中运行确切的查询返回了正确的帖子。除了 post_status 和 name(不言自明)之外,发布产品的查询看起来完全相同......但返回数组中的正确帖子。

最佳答案

好的,所以失败不在上面发布的代码中,而是在 post_status 本身的注册中:

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' );

有问题的部分是

 'public' => false

并且必须更改为

'public' => true

我不知道 public 属性影响查询,即使你查询 ID。过期产品的 ID 为 103,$post = new WP_Query('p=103'); 不会返回单个帖子,其中 $post = get_post(103); 确实返回了正确的帖子。

也许这可以防止将来遇到类似情况的人头疼。

关于php - woocommerce 过期产品自定义 post_status,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31450231/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com