Woocommerce(Wordpress插件)以编程方式生成的产品无法访问客户

时间:2014-06-06 13:01:07

标签: php wordpress wordpress-plugin woothemes

我正在使用WordPress 3.9.1和最新版本的WooCommerce(2.1.10),我正在尝试创建一个“支付您的发票”页面,人们将他们的发票号和金额直接转到结帐页面。

我现在这样做的方式:

我有一个页面,其中包含人们输入金额的表单:

<form action="#" onsubmit="location.href = 'http://protexfs.co/invoicepage/?date=' + this.elements.date.value; return false;">
<input type="text" name="date">
<input type="submit" value="Go">
</form>

提交按钮会显示一个页面,该页面会自动生成相同数量的Woocommerce产品并将其添加到购物车并自动重定向到结帐页面(我使用Insert PHP插件满足我所有的PHP需求):

[insert_php]
//empty cart
global $woocommerce;
$woocommerce->cart->empty_cart();
// Remove default cart message
$woocommerce->clear_messages();

//price
$invoiceprice = filter_input(INPUT_GET,"date",FILTER_SANITIZE_STRING);

//Generate title
$timestampedtitle = "Date: ".date("d/m/Y")." Amount: £".$invoiceprice;

//Generate message
$message = date_timestamp_get(date_create())." Date: ".date('m/d/Y h:i:s a', time())." Invoice amount: £".$invoiceprice;

$post = array(
'post_author' => '2',
'post_status' => "publish",
'post_title' => $timestampedtitle,
'post_content' => $message,
'post_parent' => '',
'post_type' => "product",
//'post_status' => 'private',
);

//Create post
$post_id = wp_insert_post( $post, $wp_error );
if($post_id){
$attach_id = get_post_meta($product->parent_id, "_thumbnail_id", true);
add_post_meta($post_id, '_thumbnail_id', $attach_id);
}
wp_set_object_terms($post_id, 'simple', 'product_type');
update_post_meta( $post_id, '_visibility', 'search' );
update_post_meta( $post_id, '_stock_status', 'instock');
update_post_meta( $post_id, '_virtual', 'yes');
update_post_meta( $post_id, '_regular_price', $invoiceprice );
update_post_meta( $post_id, '_sale_price', $invoiceprice );
update_post_meta( $post_id, '_purchase_note', "" );
update_post_meta( $post_id, '_featured', "no" );
update_post_meta( $post_id, '_weight', "" );
update_post_meta( $post_id, '_length', "" );
update_post_meta( $post_id, '_width', "" );
update_post_meta( $post_id, '_height', "" );
update_post_meta($post_id, '_sku', "");
update_post_meta( $post_id, '_product_attributes', array());
update_post_meta( $post_id, '_sale_price_dates_from', "" );
update_post_meta( $post_id, '_sale_price_dates_to', "" );
update_post_meta( $post_id, '_price', $invoiceprice );
update_post_meta( $post_id, '_sold_individually', "" );
update_post_meta( $post_id, '_manage_stock', "no" );
update_post_meta( $post_id, '_backorders', "no" );
update_post_meta( $post_id, '_stock', "" );
update_post_meta( $post_id, '_et_pb_page_layout', 'et_full_width_page' );

if( $woocommerce->cart ) {
     $woocommerce->cart->add_to_cart( $post_id, $quantity=1 );}

$url = $woocommerce->cart->get_checkout_url();
header("Location: $url");
[/insert_php]

只要我已登录,这似乎完美无缺。但是,如果用户未登录,产品仍会生成但无法添加到购物车中,显示以下消息:“抱歉,这产品无法购买。“ (这毁坏了整个事情)。

奇怪的是,我通过WooCommerce界面创建的任何其他产品都可以由访客访问(因此,如果我有一个公开的产品,我以编程方式更改其价格并将其添加到购物车,它可以工作 - &gt;但是当两个人同时点击按钮时会产生问题。)

在您提问之前,我已在WooCommerce设置中启用了访客结帐。

有关如何解决此问题的任何想法? (或者可能是完全不同的方式来实现我的目标?)

维拉德

4 个答案:

答案 0 :(得分:1)

我刚刚遇到了复合产品的同样问题。

我解决它的方法是从错误信息向后工作。

我从wp-content目录开始:

$ ack "Sorry, this product cannot be purchased."

注意:ackgrep非常相似,但更好。

这会返回以下结果(您的结果会因您安装的插件而异):

plugins/woocommerce/includes/class-wc-cart.php
825:                wc_add_notice( __( 'Sorry, this product cannot be purchased.', 'woocommerce' ), 'error' );

plugins/woocommerce-composite-products/includes/class-wc-cp-display.php
118:            'i18n_unavailable_text'                    => __( 'Sorry, this product cannot be purchased at the moment.', 'woocommerce-composite-products' ),

从那里,我注意到从i18n_unavailable_text到我的原始搜索字符串有一个woocommerce i18n映射。

为了不错过任何其他事件,我努力ack编辑:

$ ack i18n_unavailable_text

那产生了:

plugins/woocommerce/assets/js/frontend/add-to-cart-variation.js
392:                    $variation_form.find( '.single_variation' ).html( '<p>' + wc_add_to_cart_variation_params.i18n_unavailable_text + '</p>' );

plugins/woocommerce/includes/class-wc-frontend-scripts.php
197:                'i18n_unavailable_text'            => esc_attr__( 'Sorry, this product is unavailable. Please choose a different combination.', 'woocommerce' ),

plugins/woocommerce-composite-products/assets/js/add-to-cart-composite.js
2948:                       composite.disable_add_to_cart( wc_composite_params.i18n_unavailable_text );

plugins/woocommerce-composite-products/includes/class-wc-cp-display.php
118:            'i18n_unavailable_text'                    => __( 'Sorry, this product cannot be purchased at the moment.', 'woocommerce-composite-products' ),

有了这个清单,我启动了我的文本编辑器并查看了我认为相关的两个结果:

plugins/woocommerce-composite-products/assets/js/add-to-cart-composite.js
2948:                       composite.disable_add_to_cart( wc_composite_params.i18n_unavailable_text );
plugins/woocommerce/includes/class-wc-cart.php
825:                wc_add_notice( __( 'Sorry, this product cannot be purchased.', 'woocommerce' ), 'error' );

我在我的浏览器中为js文件设置了一个断点,顺便说一句,在我的情况下我必须移动到位,因为当然浏览器使用的是缩小版本,没有源映射。那个断点没有被击中,所以我进入了php调试会话。这成功了,让我进一步深入兔子洞(原谅我的vim行号 - 我在vim中使用set relativenumber - 但plugins/woocommerce/includes/class-wc-cart.php中的相关行号是824-825):

   2       // Check product is_purchasable
   1       if ( ! $product_data->is_purchasable() ) {
825          wc_add_notice( __( 'Sorry, this product cannot be purchased.', 'woocommerce' ), 'error' );
   1         return false;
   2       }

文档:$product_data->is_purchasable()

我使用kint进行调试,所以我根据上面文档中的if语句添加了一些调试输出,以查看检查可购买性失败的原因:

   2       // Check product is_purchasable
   1       if ( ! $product_data->is_purchasable() ) {
825          d(! $product_data->exists());
   1         d($product_data->get_price() === '');
   2         d($product_data->post->post_status !== 'publish');
   3         d(! current_user_can( 'edit_post', $product_data->id ));
   4         wc_add_notice( __( 'Sorry, this product cannot be purchased.', 'woocommerce' ), 'error' );
   5         return false;
   6       }

这告诉我$product_data->post->post_status !== 'publish' bool FALSE。那当然意味着我的帖子不知何故发布了。当我运行这个SQL查询时(10962是罪魁祸首产品/帖子的id而wp_4_posts是我的wordpress网站帖子的表名,这导致另一个较低的梯级进入兔子洞表,这篇文章的所在地:

SELECT post_status FROM wp_4_posts WHERE id = '10962'

返回post_status: publish。现在有人向我开枪是我的直接反应。但是,我也注意到了:

$product_data->get_price() === '' bool FALSE

因此该产品的价格未正确计算。

再次访问文档,这次是$product_data->get_price()

在考虑了几分钟之后,这让我很快意识到我没有为产品添加基本价格,认为已经指定了&#34; Per-Item-Pricing&#34;,我不会&# 39; t必须设定基本价格。祸了我。事实证明,这在Composite Products documentation

中有很好的记录

composite products per item pricing documentation

答案 1 :(得分:0)

我之前见过这个问题。有问题的产品缺少一些post meta。 添加产品后比较post_meta表,然后编辑产品,保存并再次比较表格。检查WooCommerce添加了哪些密钥。

需要严格选择元键才能购买产品。

SELECT * FROM wp_postmeta WHERE post_id = '1234567' ORDER BY 'meta_key'

答案 2 :(得分:0)

我刚遇到类似的问题,我想分享我为解决问题所做的工作。首先,我希望用户能够在网站上购买具有可变价格的添加(如craigslist),具体取决于您选择的选项和添加的长度。所以很自然地我无法创造人们可以购买的固定产品。这些添加内容将在以后发布(由于它与新闻播放器的纸质版本相关联),因此添加将在状态&#34; future&#34;中创建。和wordpress将呈现他们&#34;发布&#34;到达日期。

当我以管理员身份登录时,一切正常,但是当以普通用户身份登录时,人们无法购买添加,错误&#34;抱歉,此产品无法购买&#34;出现了。我所做的是许多人根本不推荐的(甚至是我自己),但这是我在有限时间内找到的唯一解决方案。

Woocommerce验证这些东西,如果产品是可购买的,则按顺序验证:

产品存在 产品有价格(postmeta _price!=&#34;&#34;) 产品在&#34;发布&#34;状态或当前用户可以编辑产品(例如管理员)

我将验证添加到最后一个以允许购买产品,如果当前用户是产品的作者(因此创建添加的人将能够购买,但没有其他人)。

所以在第690行的文件woocommerce / includes / abstracts / abstract-wc-product.php(来自你的插件目录)中你有这个

elseif ( $this->post->post_status !== 'publish' && ! current_user_can( 'edit_post', $this->id )

将其更改为

elseif ( $this->post->post_status !== 'publish' && ! current_user_can( 'edit_post', $this->id ) && $this->post->post_author != get_current_user_id()) {

我不推荐这个,如果你可以避免它,因为它的缺点是如果更新woocommerce,它可能会重新下载此文件,并且更改可能会丢失。但如果它是你唯一的解决方案(主要是由于时间限制而不是过多考虑),那么...

答案 3 :(得分:0)

如上所述,解决此问题的方法是:

我解决问题的方法是手动创建~50种产品(因此用户可以访问)。每当用户创建新发票(在文本字段中放置一个值并按下确定)时,随机选择其中一个产品,其价格将更改为输入的值。这样,如果多人同时点击“确定”按钮,用户就可以访问该产品并且不会搞砸。