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 测试