From 3ceb337d30f0c07ccacd6544059827d216963a0a Mon Sep 17 00:00:00 2001 From: boulea7 Date: Fri, 9 Oct 2026 03:41:54 +0800 Subject: [PATCH] fix(wordpress): map app.env to WP_ENVIRONMENT_TYPE --- documentation | 2 +- src/WordPress/Bootstrap.php | 9 + .../WordPress/BootstrapEnvironmentTest.php | 174 ++++++++++++++++++ 3 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 tests/Unit/WordPress/BootstrapEnvironmentTest.php diff --git a/documentation b/documentation index e85d8d36..3fd29977 160000 --- a/documentation +++ b/documentation @@ -1 +1 @@ -Subproject commit e85d8d364c92617d17f51d753a6bc91852503a69 +Subproject commit 3fd29977af8aa4651a981782ceab42b74d7f726b diff --git a/src/WordPress/Bootstrap.php b/src/WordPress/Bootstrap.php index 8129107d..d187d24e 100644 --- a/src/WordPress/Bootstrap.php +++ b/src/WordPress/Bootstrap.php @@ -391,6 +391,15 @@ private function defineWordPressConstants(): void Constant::queue('JETPACK_DEV_DEBUG', $debugMode); + if (! function_exists('getenv') || getenv('WP_ENVIRONMENT_TYPE') === false) { + Constant::queue('WP_ENVIRONMENT_TYPE', match (config('app.env')) { + 'local' => 'local', + 'dev', 'development', 'testing' => 'development', + 'staging' => 'staging', + default => 'production', + }); + } + foreach ((array) config('wordpress.constants', []) as $key => $value) { $key = strtoupper((string) $key); Constant::queue($key, $value); diff --git a/tests/Unit/WordPress/BootstrapEnvironmentTest.php b/tests/Unit/WordPress/BootstrapEnvironmentTest.php new file mode 100644 index 00000000..599e810a --- /dev/null +++ b/tests/Unit/WordPress/BootstrapEnvironmentTest.php @@ -0,0 +1,174 @@ +registerWordPressConstants(); + + self::assertTrue(WP_DEBUG); + self::assertSame('local', constant('WP_ENVIRONMENT_TYPE')); + } + + #[DataProvider('environmentMappings')] + public function test_application_environment_is_mapped(?string $environment, string $expected): void + { + putenv('WP_ENVIRONMENT_TYPE'); + $this->registerWordPressConstants($environment); + + self::assertSame($expected, constant('WP_ENVIRONMENT_TYPE')); + } + + #[DataProvider('debugValues')] + public function test_environment_does_not_depend_on_debug_mode(bool $debug): void + { + putenv('WP_ENVIRONMENT_TYPE'); + $this->registerWordPressConstants(debug: $debug); + + self::assertSame($debug, WP_DEBUG); + self::assertSame('local', constant('WP_ENVIRONMENT_TYPE')); + } + + #[DataProvider('nativeEnvironments')] + public function test_native_environment_prevents_fallback_constant(string $environment): void + { + putenv('WP_ENVIRONMENT_TYPE='.$environment); + $this->registerWordPressConstants(); + + self::assertFalse(defined('WP_ENVIRONMENT_TYPE')); + self::assertSame($environment, getenv('WP_ENVIRONMENT_TYPE')); + } + + #[DataProvider('explicitValues')] + public function test_configured_environment_is_not_normalized(mixed $value): void + { + putenv('WP_ENVIRONMENT_TYPE'); + $this->registerWordPressConstants(constants: ['wp_environment_type' => $value]); + + self::assertSame($value, constant('WP_ENVIRONMENT_TYPE')); + } + + public function test_configured_constant_still_applies_with_native_environment(): void + { + putenv('WP_ENVIRONMENT_TYPE=production'); + $this->registerWordPressConstants(constants: ['WP_ENVIRONMENT_TYPE' => 'staging']); + + self::assertSame('staging', constant('WP_ENVIRONMENT_TYPE')); + self::assertSame('production', getenv('WP_ENVIRONMENT_TYPE')); + } + + #[DataProvider('explicitValues')] + public function test_predefined_constant_is_not_overwritten(mixed $value): void + { + putenv('WP_ENVIRONMENT_TYPE=production'); + define('WP_ENVIRONMENT_TYPE', $value); + $this->registerWordPressConstants(constants: ['WP_ENVIRONMENT_TYPE' => 'development']); + + self::assertSame($value, constant('WP_ENVIRONMENT_TYPE')); + } + + /** + * @return array + */ + public static function environmentMappings(): array + { + return [ + 'local' => ['local', 'local'], + 'dev' => ['dev', 'development'], + 'development' => ['development', 'development'], + 'testing' => ['testing', 'development'], + 'staging' => ['staging', 'staging'], + 'production' => ['production', 'production'], + 'prod' => ['prod', 'production'], + 'unknown' => ['preview', 'production'], + 'empty' => ['', 'production'], + 'missing' => [null, 'production'], + ]; + } + + /** + * @return array + */ + public static function debugValues(): array + { + return ['enabled' => [true], 'disabled' => [false]]; + } + + /** + * @return array + */ + public static function nativeEnvironments(): array + { + return [ + 'local' => ['local'], + 'development' => ['development'], + 'staging' => ['staging'], + 'production' => ['production'], + 'empty' => [''], + 'invalid' => ['preview'], + ]; + } + + /** + * @return array + */ + public static function explicitValues(): array + { + return [ + 'valid' => ['staging'], + 'empty' => [''], + 'invalid' => ['preview'], + 'false' => [false], + ]; + } + + /** + * @param array $constants + */ + private function registerWordPressConstants(?string $environment = 'local', array $constants = [], bool $debug = true): void + { + $app = new Application(dirname(__DIR__, 3)); + $app->instance('config', new Repository([ + 'app' => ['env' => $environment, 'debug' => $debug, 'url' => 'http://environment.test'], + 'wordpress' => ['constants' => $constants], + ])); + $app->instance('request', Request::create('/')); + $app->instance('constant.manager', new ConstantManager); + Facade::setFacadeApplication($app); + + $bootstrap = new Bootstrap( + new ConsoleDetectionService(new LaravelConsoleDetector($app)), + new LaravelDebugDetector($app), + \Mockery::mock(Action::class), + ); + + $bootstrap->register(); + } +}