【问题标题】:what is a wordpress/woocommerce hook tha fire after a woocommerce product saved保存 woocommerce 产品后,什么是 wordpress/woocommerce 钩子?
【发布时间】:2019-05-28 13:27:52
【问题描述】:

我想在用户创建并保存后将 woocommerce 产品数据通过soap-client发送到邮政公司的网络服务。所以我需要一个在用户创建产品后触发的钩子。我搜索了很多,找到了一些 word press 和 woocommerce 钩子,但它们都没有做我的工作。发送日期后,Web 服务返回一个应设置为产品 sku 的 ID。听到是我的函数代码:(参数来自 save_post_product 钩子)

function productPublished ($ID , $post , $update){
$product = wc_get_product( $post->ID);
$user = get_option ('myUsername');
$pass = get_option ('myPassword');
$name = $product->get_name();
$price = $product->get_regular_price();
$weight = $product->get_weight() * 1000;
$count = $product->get_stock_quantity();
$description = $product->get_short_description();
$result = $client -> AddStuff ([
    'username' => $user,
    'password' => $pass,
    'name' => $name,
    'price' => $price,
    'weight' => $weight, 
    'count' => $count,
    'description' => $description,
    'percentDiscount' => 0
]);
$stuff_id=(int)$result->AddStuffResult;
update_post_meta($product->get_id(),'_sku',$stuff_id);
}

我使用save_post_product 操作。用户在输入名称和价格等之前单击新产品后似乎会触发它,因为默认产品数据发送到 Web 服务和 sku 在我输入任何数据之前生成并保存。 我使用transition_post_status 并将此代码添加到我的函数中:

if($old_status != 'publish' && $new_status == 'publish' && 
!empty($post->ID) && in_array( $post->post_type, array( 'product') )){
code...}

结果与save_post_product 相同。 我使用publish_product 操作,结果没有改变。 我使用draft_to_publish 钩子。我输入产品名称和描述后,它似乎会触发。名称发送到网络服务,但价格和重量没有。 sku 没有保存到数据库中(为什么??)。 我知道还有另一个问题here 声称save_post 在发布后触发并保存到数据库。但我认为 woocommerce 是不同的。似乎在输入名称和描述之后以及在输入价格等之前保存帖子。 有什么建议???

【问题讨论】:

  • save post after entering name and description and before entering price and etc 这些字段可能保存在postmeta 中,因此您需要一个在保存帖子元数据后触发的钩子(这可能很难,因为插件经常使用帖子元数据)。例如,查看 PHPmyAdmin 中的 posts 表,您不会找到名为 priceweight 的列。因此,为了能够存储该数据,通常使用元表(这就是它的用途)。元表就像key => value 存储而不是“普通”表。

标签: php wordpress woocommerce hook-woocommerce


【解决方案1】:

您想要的操作是:

add_action('woocommerce_update_product', 'productPublished');

add_action('woocommerce_new_product', 'productPublished');

function productPublished($product_id){
    //...
}

您可以在此处的 Woo 源代码中找到它们(触发它们的位置):

https://docs.woocommerce.com/wc-apidocs/source-class-WC_Product_Data_Store_CPT.html#237

我实际上是通过首先找到用于保存产品的源代码的位置来向后查找它们,然后在这些方法中查找挂钩(创建/更新)。

 //found on Line 134 method create
 do_action( 'woocommerce_new_product', $id );


 //found on Line 237 method update
 do_action( 'woocommerce_update_product', $product->get_id() );

您还必须更改此行:

function productPublished ($ID , $post , $update){
    $product = wc_get_product( $post->ID);
}

function productPublished($product_id){
    $product = wc_get_product( $product_id);
   //....
}

我认为其他参数(缺少的)与您的代码无关。比如更新或新产品,我也没有看到 $post 用于获取我们已经拥有的产品 ID。

更新(确定回调参数)

如果您不确定回调的参数,您可以查看源代码(就像我在上面所做的那样)或者如果您可以在文档中找到它或者作为最后的手段,您可以简单地输出它们。输出它们的最佳方式是这 3 个

这是一个示例,我使用以 WordPress 为模型的最小/简化的工作挂钩系统构建。出于测试原因,并且因为当您知道它是如何工作时,构建它真的不那么难:

//global storage (functions, not classes)
global $actions;
$actions = [];

//substitute wordpress add_action function (for testing only) 
function add_action($action, $callback, $priorty=10, $num_args=1){
    global $actions;
    $actions[$action][] = [
         'exec' => $callback,
         'priorty'=>$priorty,
         'num_args' => $num_args
    ];

}
//substitute wordpress do_action function (for testing only) 
function do_action($action, ...$args){
    // PHP5.6+ variadic (...$args) wraps all following arguments in an array inside $args (sort of the opposite of func_get_args)
    global $actions;

    if(empty($actions[$action])) return;
    //sort by priory
    usort($actions[$action], function($a,$b){
       //PHP7+ "spaceship" comparison operator (<=>)
       return $b['priorty']<=>$a['priorty'];
    });

    foreach($actions[$action] as $settings){
        //reduce the argument list
        call_user_func_array($settings['exec'], array_slice($args, 0, $settings['num_args']));
    }
}

//test callback
function callback1(){
     echo "\n\n".__FUNCTION__."\n";
    print_r(func_get_args());
}

//test callback
function callback2(){
    echo "\n\n".__FUNCTION__."\n";
    try{
        //throw an empty exception
        throw new Exception;
    }catch(\Exception $e){
         //pre tags preserve whitespace (white-space : pre)
        echo "<pre>";
        //output the stacktrace of the callback
        echo $e->getTraceAsString();
        echo "\n\n</pre>";
   }
}

//Register Hook callbacks, added in opposite order, sorted by priority
add_action('someaction', 'callback2', 5, 4);
add_action('someaction', 'callback1', 1, 5);

//execute hook
do_action('someaction', 1234, 'foo', ['one'=>1], new stdClass, false);

输出:

callback2
<pre>#0 [...][...](25): callback2(1234, 'foo', Array, Object(stdClass))
#1 [...][...](52): do_action('someaction', 1234, 'foo', Array, Object(stdClass), false)
#2 {main}

</pre>

callback1
Array
(
    [0] => 1234
    [1] => foo
    [2] => Array
        (
            [one] => 1
        )

    [3] => stdClass Object
        (
        )
    [4] =>
)

Sandbox

Stacktrace 正如您在第一个输出中看到的那样,我们有一个完整的应用程序堆栈跟踪(减去编辑信息),包括函数调用和用于这些调用的参数。另请注意,在此示例中,我第二次注册它,但优先级(在add_action 中设置)使其首先执行。最后,仅使用了 5 个参数中的 4 个(也与 add_action 的调用方式有关)。

所以do_action 是这样调用的(带有“动作”和其他 5 个参数):

 do_action('someaction', 1234, 'foo', Array, Object(stdClass), false)

实际的回调是这样调用的(没有“action”,只有 4 个其他参数):

 callback2(1234, 'foo', Array, Object(stdClass))

Function Arguments 这有点困难,但它不会给你原始调用,所以你不会知道 args 的最大数量(你可以从调用堆栈跟踪中的 do_action )。但是,如果您只是想快速查看传入的数据,那么它是完美的。另外我应该提到这个使用所有 5 个参数,您可以在数组中清楚地看到第二个输出。 [4] =&gt; 是假的,这通常是print_r 显示假的方式(因为只是空的)。

调试回溯不幸的是,debug_print_backtrace 在沙箱中被禁用(出于安全原因),并且异常堆栈跟踪被大量编辑(通常它具有文件名和函数被调用的行并位于) 也是出于安全原因。这两个都可以从连接到数据库之类的东西返回参数,例如,它将包含纯文本的数据库密码。不管怎样,debug_print_backtrace 非常接近异常堆栈跟踪的样子。

夏天

但无论如何,这应该让您了解数据的样子。我们可以使用这样的函数(和反射)在运行时询问应用程序。我相信还有其他/更多方法可以做类似的事情。

PS。不言而喻,但无论如何我都会说,上面的这些方法适用于任何 PHP 函数,并且非常有用。同样如上所述,您永远不应该在实时生产机器上显示堆栈跟踪。

无论如何,祝你好运。

【讨论】:

  • 感谢您提及如何找到这些钩子。它非常有用。我找到了另一种使用 woocommerce_process_product_meta 的方法。优先级必须在 20 以上。如何找到可以使用的参数列表?
  • 要么查看源代码,要么在你的回调函数中使用func_get_args我会展示一个例子
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多