inpsyde/wp-context

WordPress 网站运行环境检查的单类实用工具。

1.5.0 2023-01-09 06:27 UTC

This package is auto-updated.

Last update: 2024-09-21 14:48:04 UTC


README

WordPress 网站当前请求环境的单类实用工具。

PHP Quality Assurance

如何使用

这是一个 Composer 包,而不是插件,因此首先需要通过 Composer 进行安装。

之后,假设 Composer 自动加载文件已加载,在加载过程非常早期,可以像这样实例化 WpContext

$context = Inpsyde\WpContext::determine();

此库不实现单例模式,也不缓存当前上下文的检索,因此最好将创建的实例保存在插件/主题/包/应用程序的全球可访问位置。

拥有 WpContext 的实例后,可以通过其 is 方法或上下文特定方法来检查当前上下文。

例如

use Inpsyde\WpContext;

$context = WpContext::determine();
if ($context->is(WpContext::AJAX, WpContext::CRON)) {
    // stuff for requests that are either AJAX or WP cron
} elseif ($context->isBackoffice()) {
    // stuff for "backoffice" requests (WP admin)
}

WpContext::is() 方法方便检查多个上下文,上下文特定方法可能更适合检查单个上下文。

可以检查的所有上下文列表如下

  • ->is(WpContext::CORE) / ->isCore()
  • ->is(WpContext::FRONTOFFICE) / ->isFrontoffice()
  • ->is(WpContext::BACKOFFICE) / ->isBackoffice()
  • ->is(WpContext::AJAX) / ->isAjax()
  • ->is(WpContext::LOGIN) / ->isLogin()
  • ->is(WpContext::REST) / ->isRest()
  • ->is(WpContext::CRON) / ->isCron()
  • ->is(WpContext::CLI) / ->isWpCli()
  • ->is(WpContext::XML_RPC) / ->isXmlRpc()
  • ->is(WpContext::INSTALLING) / ->isInstalling()
  • ->is(WpContext::WP_ACTIVATE) / ->isWpActivate()

关于 "核心" 和 "安装" 上下文

WpContext::isCore() 检查常量 ABSPATH 是否已定义,这意味着当所有其他上下文检查都为真时,它通常也为真,但 WpContext::isInstalling() 是一个例外(更多内容见下文)。另一个可能的例外是 WordPress 加载之前运行的 WP CLI 命令。

WpContext::isInstalling() 在常量 WP_INSTALLING 定义且为真时为真,这意味着 WordPress 正在安装或升级。

在此阶段,WpContext 对所有其他上下文返回 false(除 WpContext::isWpCli() 外,如果安装/更新是通过 WP CLI 进行的,则将为真)。

例如,如果启动了 cron 请求,并且 WordPress 在该请求期间将常量 WP_INSTALLING 设置为真,则 WpContext::isCron() 将为 false,就像 WpContext::isCore() 一样。

原因是 WordPress 在安装期间可能不会按预期运行。

例如以下代码

if (Inpsyde\WpContext::determine()->isCore()) {
    return get_option('some_option');
}

可能看起来非常好,但如果 WP_INSTALLING 为真,则可能会损坏,在这种情况下,选项表可能根本不存在。多亏了 WpContext::isCore()WP_INSTALLING 为真时返回 false,上面的 get_option 调用在安装期间(当时不可调用)不会执行。

关于 "安装" 和 "激活" 上下文

上一节中提到

WpContext::isInstalling() 在常量 WP_INSTALLING 定义且为真时为真

但有一个例外。

当访问 /wp-activate.php 时,常量 WP_INSTALLING 定义且为真,然而在该情况下通常适用的问题(WP 不可靠)不适用。事实上,在 /wp-activate.php 中,没有发生 "安装",WP 已完全加载。

这就是为什么 /wp-activate.php 是一种“特殊情况”,WP Context 可以通过 WpContext::isWpActivate() 来确定这种情况。当它返回 true 时,WpContext::isInstalling() 将返回 false,而 WpContext::isCore() 将返回 true,即使定义了 WP_INSTALLING 且为 true。

请注意,/wp-activate.php 仅适用于多站点安装,而在单站点安装中,WpContext::isWpActivate() 总是返回 false。

好吧,那为什么?

WordPress 有核心函数和常量来确定当前请求的上下文,那么为什么还需要额外的包呢?

有多个原因。

  • 并非所有上下文都有确定的方式。例如,如何在“前台”上下文中确定?还有登录界面呢?
  • 某些上下文有专门的常量/函数,但仅在请求流程的后期才可用。例如,可以通过 REST_REQUEST 常量检查 REST 请求,但这仅在非常晚的时候才定义。WpContext::isRest() 可以在非常早的时候使用。
  • 单元测试。任何依赖于 PHP 常量的逻辑都会使单元测试变得困难,因为它迫使测试在单独的进程中运行,以便能够测试相同常量的不同值。此外,在没有加载 WordPress 的情况下运行测试时,可能需要“模拟”一些 WordPress 函数、常量、全局变量等。如以下文档所述,这个包可以使测试变得非常容易。

测试使用 WpContext 的代码

考虑到 WpContext 使用常量和函数来确定当前 WordPress 上下文,测试使用它的代码可能会很困难,尤其是在 WordPress 完全未加载的情况下。

在测试中,可以通过调用 WpContext::new 来获取 WpContext 的实例,而不是调用 WpContext::determine(),然后使用 WpContext::force() 方法将其设置为所需的上下文

use Inpsyde\WpContext;

$context = WpContext::new()->force(WpContext::AJAX);

assert($context->isAjax());
assert($context->isCore());

当“强制”的上下文不同于 INSTALLINGCLI 时,上下文 CORE 也会设置为 true,因此不可能在 WordPress 核心之外进行 WordPress AJAX 请求。

除了 CORE 之外,唯一可以与其他上下文相关联的上下文是 CLI。然而,force 方法只接受单个上下文,因此通过使用它无法“模拟”既是 CLI 也是 CRON 的请求。

为此,WpContext 有一个 withCli 方法,与 force 不同,它不会覆盖当前上下文,而只是“附加” CLI 上下文。

例如

use Inpsyde\WpContext;

$context = WpContext::new()->force(WpContext::CRON)->withCli();

assert($context->isCron());
assert($context->isCore());
assert($context->isWpCli());

请注意,仍然可以使用 $context->force(WpContext::CLI) 来“模拟”只有 WP CLI 的请求,甚至不是 CORE

许可证

此存储库是免费软件,并按照 GNU 通用公共许可证第 2 版或(根据您的选择)任何更新版本的条款发布。有关完整许可证,请参阅 LICENSE

贡献

欢迎所有反馈/错误报告/拉取请求。

在发送 PR 之前,请确保 composer qa 没有输出错误。

它将依次运行