当触发WooCommerce_Order_Status_Changed挂接时,WooCommerce管理通知不起作用
我是WordPress开发新手,目前遇到了死胡同。
我希望在更改订单状态后在WooCommerce订单中显示管理通知。
使用以下代码,通知不会出现:
<?php
class TestNotice {
public function testTheNotice() {
add_action('woocommerce_order_status_changed', [$this, 'test'], 10, 4);
}
public function test(int $id, string $statusFrom, string $statusTo, WC_Order $order)
{
add_action('admin_notices', [$this, 'notice']);
}
public function notice()
{
?>
<div class="notice notice-error is-dismissible">
<p>This notice appears on the order page.</p>
</div>
<?php
}
}
$testNotice = new TestNotice();
$testNotice->testTheNotice();
我已尝试将";ADMIN_NOTICES&QOOT;操作的&QOOT;PRIORITY&QOOT;参数设置为20
,但没有成功(我认为如果嵌套的操作与第一次调用的操作相同,则会很有用)。
但是,当我在testTheNotice()
方法中直接调用";admin_Notitions";action(因此不调用";WooCommerce_Order_Status_Changed";action)时,它可以工作(在每个管理页面上,这不是我想要的)。
我以为这是因为notice()
不知何故没有被识别,但事实并非如此:下面的代码显示此通知显示在订单页上。&q;显示在空白页上(这不是我想要的,仅用于测试目的)。
<?php
class TestNotice {
public function testTheNotice() {
add_action('woocommerce_order_status_changed', [$this, 'test'], 10, 4);
}
public function test(int $id, string $statusFrom, string $statusTo, WC_Order $order)
{
call_user_func([$this, 'notice']); die();
}
public function notice()
{
?>
<div class="notice notice-error is-dismissible">
<p>This notice appears on the order page.</p>
</div>
<?php
}
}
$testNotice = new TestNotice();
$testNotice->testTheNotice();
我知道WooCommerce管理通知有一个特殊的类和方法,在notice()
中编写下面的代码会显示一个通知,但带有紫色边框(因为";update";css类,我还没有找到如何更改它),而不是红色边框(由于";Error";css类,我不知道如何应用它)。
$adminNotice = new WC_Admin_Notices();
$adminNotice->add_custom_notice("Test",'<p>This notice appears on the order page.</p>');
$adminNotice->output_custom_notices();
解决方案
问得好。这让我很好奇,也让我开始钻研这个WC_Admin_Notices
类。这就是我的发现!
好,在我谈论WC_Admin_Notices
类之前,让我们先来谈谈您的第一个问题!
通知未显示
因为当woocommerce_order_status_changed
钩子触发时,没有与其关联的屏幕,而且它不仅仅是通知,例如,如果您尝试执行print_r
和/或echo
,它们也不会显示任何内容,因为没有与该钩子关联的屏幕。找到该钩子的唯一方法是使用die
函数。为了测试这一点,您可以执行以下操作:
add_action('woocommerce_order_status_changed', 'test', 99, 4);
function test($order_id, $old_status, $new_status, $order_object)
{
die('You hit the right hook!');
}
但如果您将die('You hit the right hook!')
函数替换为echo
或print_r
,无论您将挂钩的优先级设置得多高,它们都不会显示任何内容。
当您使用WC_Admin_Notices
类时,它变得很有趣。如果没有与woocommerce_order_status_changed
挂钩相关联的屏幕,那么这个类如何工作?好吧,这是怎么做的:
class-wc-admin-notices.php
Class
- 它有一个名为
$notices
的属性,这是一个简单的空数组。 - 当您调用
add_custom_notice
方法时,它会将您给它的值存储到数据库和";Options&Quot;表中。关键字将是";WooCommerce_admin_Notify_{您给出的名称,例如test}";,而值将是您定义的消息/通知。这就是它的全部功能!它将您的消息/通知存储到数据库中。 - 当您调用
output_custom_notices
方法时,它将检查$notices
数组,并检查数据库中存储在Options表中的任何键值对,格式为我在第2号中提到的格式!然后,它在以下路径中使用名为html-notice-custom.php
的模板:
您的website.com;wp-Content&>插件&>WooCommerce&>包括>;admin&>视图>;html-Notify-Custom.php
html-notice-custom.php
Template
html-notice-custom.php
文件负责输出自定义通知的html标记,它将为它们提供一个名为updated
的类,该类将触发具有浅紫色的css规则。
因此WC_Admin_Notices
类的总体工作流是:
- 将您的自定义消息存储到数组或数据库
- 在屏幕加载时检索存储的键和值对!
从技术上讲,这就是它所做的一切,好吧,最简单地说!
因为我们不需要自定义浅紫色模板,所以我们可以使用WC_Admin_Notices
使用的工作流并编写我们自己的解决方案,而不使用WC_Admin_Notices
类。
我们可以使用以下方法之一:
- 使用
$_SESSION
+admin_notices
挂钩 组合
- 使用
cookie
或local storage
+admin_notices
挂钩 组合
- 使用
database
+admin_notices
挂钩 组合
我认为,如果我们使用
$_SESSION
+admin_notices
钩子方法,它将既安全又快速,甚至不需要向数据库查询简单的文本字符串。我此时此刻能想到的解决方案是:
代码进入活动主题的functions.php
文件。
add_action('woocommerce_order_status_changed', 'test', 99, 4);
function test($order_id, $old_status, $new_status, $order_object)
{
if ( $order_object && ($old_status != $new_status) )
{
$notice = 'This notice appears on the order page.';
session_start();
$_SESSION['your_custom_message_name'] = $notice;
}
}
add_action('admin_notices', 'your_them_displaying_custom_admin_notice');
function your_them_displaying_custom_admin_notice()
{
session_start();
if (isset($_SESSION['your_custom_message_name'])) {
?>
<div class='notice notice-error is-dismissible'>
<p><?php echo $_SESSION['your_custom_message_name'] ?></p>
</div>
<?php
unset($_SESSION['your_custom_message_name']);
}
}
注意:
- 仅当有订单且
$old_status
不等于$new_status
时才有效。 - 在
$notice
变量中,我放置的是原始文本,而不是html,因为我们在admin_notices
挂钩的html部分/模板中放置了p
标记。 - 我为
div
标记使用了notice-error
类,该标记显示了通知的red color
。您可以将其替换为notice-warning
、notice-info
或notice-success
。
此答案已在WooCommerce5.7
上进行了全面测试,运行正常。
相关文章