inpsyde / wp-context
WordPress 网站运行环境检查的单类实用工具。
Requires
- php: >=7.1
Requires (Dev)
- brain/monkey: ^2.6.1
- inpsyde/php-coding-standards: ^1
- inpsyde/wp-stubs: dev-main
- mockery/mockery: ~1.3.6
- phpunit/phpunit: ~7.5.20 || ^8
- vimeo/psalm: ^4.27.0
This package is auto-updated.
Last update: 2024-09-21 14:48:04 UTC
README
WordPress 网站当前请求环境的单类实用工具。
如何使用
这是一个 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());
当“强制”的上下文不同于 INSTALLING 或 CLI 时,上下文 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 没有输出错误。
它将依次运行
- PHPCS 与 Inpsyde 代码风格 进行检查
- Psalm 检查
- PHPUnit 测试