当 woocommerce_order_status_changed 挂钩触发时,Woocommerce admin_notices 不起作用
Woocommerce admin_notices does not work when woocommerce_order_status_changed hook fires
我是 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”动作的“优先级”参数设置为20
,但没有成功(我认为如果嵌套动作与第一个电话)。
但是,当我直接在 testTheNotice()
方法中调用“admin_notices”操作(因此不调用“woocommerce_order_status_changed”操作)时,它有效(在每个管理页面上,这不是我想要的)。
我以为是因为notice()
不知何故没有被识别,但实际上是:下面的代码显示“This notice appears on the order page”。在空白页上(这不是我想要的,仅用于测试目的)。
<?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 管理员通知有一个特殊的 class 和方法,在 notice()
中编写下面的代码会显示一条通知,但带有紫色边框(因为“更新” css class,我还没有找到如何更改)而不是红色边框(这可能要归功于“错误” css class,我不知道如何申请)。
$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
class。这是我发现的!
嗯,在说WC_Admin_Notices
class之前,先来说说你的第一个问题吧!
"the notice doesn't appear"
因为当 woocommerce_order_status_changed
挂钩触发时,没有与之关联的屏幕,它不仅仅是通知,例如,如果您尝试执行 print_r
and/or 和 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
class 时会变得很有趣。如果没有与 woocommerce_order_status_changed
挂钩关联的屏幕,那么这个 class 是如何工作的?那么,方法如下:
- 它有一个名为
$notices
的 属性,它是一个简单的空数组。
- 当您调用
add_custom_notice
方法时,它会将您提供的值存储到数据库和“选项”table 中。键将是“woocommerce_admin_notice_{您为示例测试提供的名称}”,值将是您定义的 message/notice。 就是这样!它将您的 message/notice 存储到数据库中。
- 当你调用
output_custom_notices
方法时,它会检查 $notices
数组,并检查数据库中存储在选项 table 中的任何键值对,格式如下在第 2 条中提到!然后,它在以下路径中使用名为 html-notice-custom.php
的模板:
yourwebsite.com > wp-content > plugins > woocommerce > includes > admin > views > html-notice-custom.php
html-notice-custom.php
Template
html-notice-custom.php
文件负责输出自定义通知的 html 标记,它会给它们一个名为 updated
的 class,这将触发 css 具有浅紫色的规则。
所以 WC_Admin_Notices
class 的整体工作流程是:
- 将自定义消息存储到数组或数据库中
- 在屏幕加载时检索存储的键值对!
从技术上讲,这就是它所做的一切,好吧,用最简单的术语来说!
由于我们不需要那个自定义的浅紫色模板,我们可以使用 WC_Admin_Notices
使用的工作流程并编写我们自己的解决方案而不使用 WC_Admin_Notices
class.
我们可以使用以下方法之一:
- 使用
$_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,因为我们在 html section/template 中放置了一个 p
标签admin_notices
勾.
- 我使用
notice-error
class 作为 div
标签,它显示 red color
作为通知。您可以将其替换为 notice-warning
、notice-info
或 notice-success
.
这个答案已经在 woocommerce 5.7
上进行了全面测试并且工作正常。
我是 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”动作的“优先级”参数设置为20
,但没有成功(我认为如果嵌套动作与第一个电话)。
但是,当我直接在 testTheNotice()
方法中调用“admin_notices”操作(因此不调用“woocommerce_order_status_changed”操作)时,它有效(在每个管理页面上,这不是我想要的)。
我以为是因为notice()
不知何故没有被识别,但实际上是:下面的代码显示“This notice appears on the order page”。在空白页上(这不是我想要的,仅用于测试目的)。
<?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 管理员通知有一个特殊的 class 和方法,在 notice()
中编写下面的代码会显示一条通知,但带有紫色边框(因为“更新” css class,我还没有找到如何更改)而不是红色边框(这可能要归功于“错误” css class,我不知道如何申请)。
$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
class。这是我发现的!
嗯,在说WC_Admin_Notices
class之前,先来说说你的第一个问题吧!
"the notice doesn't appear"
因为当 woocommerce_order_status_changed
挂钩触发时,没有与之关联的屏幕,它不仅仅是通知,例如,如果您尝试执行 print_r
and/or 和 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
class 时会变得很有趣。如果没有与 woocommerce_order_status_changed
挂钩关联的屏幕,那么这个 class 是如何工作的?那么,方法如下:
- 它有一个名为
$notices
的 属性,它是一个简单的空数组。 - 当您调用
add_custom_notice
方法时,它会将您提供的值存储到数据库和“选项”table 中。键将是“woocommerce_admin_notice_{您为示例测试提供的名称}”,值将是您定义的 message/notice。 就是这样!它将您的 message/notice 存储到数据库中。 - 当你调用
output_custom_notices
方法时,它会检查$notices
数组,并检查数据库中存储在选项 table 中的任何键值对,格式如下在第 2 条中提到!然后,它在以下路径中使用名为html-notice-custom.php
的模板:
yourwebsite.com > wp-content > plugins > woocommerce > includes > admin > views > html-notice-custom.php
html-notice-custom.php
Template
html-notice-custom.php
文件负责输出自定义通知的 html 标记,它会给它们一个名为 updated
的 class,这将触发 css 具有浅紫色的规则。
所以 WC_Admin_Notices
class 的整体工作流程是:
- 将自定义消息存储到数组或数据库中
- 在屏幕加载时检索存储的键值对!
从技术上讲,这就是它所做的一切,好吧,用最简单的术语来说!
由于我们不需要那个自定义的浅紫色模板,我们可以使用 WC_Admin_Notices
使用的工作流程并编写我们自己的解决方案而不使用 WC_Admin_Notices
class.
我们可以使用以下方法之一:
- 使用
$_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,因为我们在 html section/template 中放置了一个p
标签admin_notices
勾. - 我使用
notice-error
class 作为div
标签,它显示red color
作为通知。您可以将其替换为notice-warning
、notice-info
或notice-success
.
这个答案已经在 woocommerce 5.7
上进行了全面测试并且工作正常。