From 29f526814f4f955f4edd136f3d1d48cbd13adfe3 Mon Sep 17 00:00:00 2001 From: Daryll Doyle Date: Thu, 13 Nov 2025 16:58:03 +0000 Subject: [PATCH 1/5] Allow caching to be skipped --- src/ModuleInitialization.php | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/ModuleInitialization.php b/src/ModuleInitialization.php index 01271cd..67e8df6 100644 --- a/src/ModuleInitialization.php +++ b/src/ModuleInitialization.php @@ -68,7 +68,7 @@ public function get_classes( string $dir ): array { $class_finder->classes(); // If we are in production or staging, cache the class loader to improve performance. - if ( ! defined( 'VIP_GO_APP_ENVIRONMENT' ) && in_array( wp_get_environment_type(), [ 'production', 'staging' ], true ) ) { + if ( $this->should_use_cache() ) { $class_finder->withCache( __NAMESPACE__, new FileDiscoverCacheDriver( $dir . '/class-loader-cache' ) @@ -82,6 +82,27 @@ public function get_classes( string $dir ): array { return $classes; } + /** + * Should we set up and use the class cache? + * + * @return bool + */ + protected function should_use_cache(): bool { + if ( defined( 'VIP_GO_APP_ENVIRONMENT' ) ) { + return false; + } + + if ( ! in_array( wp_get_environment_type(), [ 'production', 'staging' ], true ) ) { + return false; + } + + if ( defined( 'TENUP_FRAMEWORK_DISABLE_CLASS_CACHE' ) && true === TENUP_FRAMEWORK_DISABLE_CLASS_CACHE ) { + return false; + } + + return true; + } + /** * Check if the directory exists. * From 95a29869dc7d2500e9c3e95308847db296b04d3d Mon Sep 17 00:00:00 2001 From: Daryll Doyle Date: Thu, 13 Nov 2025 16:58:14 +0000 Subject: [PATCH 2/5] Test cache skipping is working --- tests/ModuleInitializationTest.php | 72 ++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/tests/ModuleInitializationTest.php b/tests/ModuleInitializationTest.php index ccf13db..6a38bdb 100644 --- a/tests/ModuleInitializationTest.php +++ b/tests/ModuleInitializationTest.php @@ -10,6 +10,7 @@ namespace TenupFrameworkTests; use PHPUnit\Framework\TestCase; +use function Brain\Monkey\Functions\stubs; /** * Test Class @@ -147,4 +148,75 @@ public function testIsClassFullyLoadable() { $this->assertInstanceOf( 'ReflectionClass', $module_init->get_fully_loadable_class( '\TenupFrameworkTestClasses\Loadable\ChildClass' ) ); $this->assertFalse( $module_init->get_fully_loadable_class( '\TenupFrameworkTestClasses\Loadable\InvalidChildClass' ) ); } + + + /** + * Ensure it returns false if VIP_GO_APP_ENVIRONMENT is defined. + * + * @return void + */ + public function test_should_use_cache_returns_false_when_vip_env_is_defined() { + define( 'VIP_GO_APP_ENVIRONMENT', true ); + $module_init = \TenupFramework\ModuleInitialization::instance(); + $reflection = new \ReflectionClass( $module_init ); + $method = $reflection->getMethod( 'should_use_cache' ); + $method->setAccessible( true ); + + $this->assertFalse( $method->invoke( $module_init ) ); + } + + /** + * Ensure it returns false in non-production or staging environments. + * + * @return void + */ + public function test_should_use_cache_returns_false_in_non_production_or_staging_env() { + stubs( + [ + 'wp_get_environment_type' => 'development' + ] + ); + + $module_init = \TenupFramework\ModuleInitialization::instance(); + $reflection = new \ReflectionClass( $module_init ); + $method = $reflection->getMethod( 'should_use_cache' ); + $method->setAccessible( true ); + + $this->assertFalse( $method->invoke( $module_init ) ); + } + + /** + * Ensure it returns false when TENUP_FRAMEWORK_DISABLE_CLASS_CACHE is defined. + * + * @return void + */ + public function test_should_use_cache_returns_false_when_disable_class_cache_is_defined() { + define( 'TENUP_FRAMEWORK_DISABLE_CLASS_CACHE', true ); + $module_init = \TenupFramework\ModuleInitialization::instance(); + $reflection = new \ReflectionClass( $module_init ); + $method = $reflection->getMethod( 'should_use_cache' ); + $method->setAccessible( true ); + + $this->assertFalse( $method->invoke( $module_init ) ); + } + + /** + * Ensure it returns true under default conditions. + * + * @return void + */ + public function test_should_use_cache_returns_true_under_default_conditions() { + stubs( + [ + 'wp_get_environment_type' => 'production' + ] + ); + + $module_init = \TenupFramework\ModuleInitialization::instance(); + $reflection = new \ReflectionClass( $module_init ); + $method = $reflection->getMethod( 'should_use_cache' ); + $method->setAccessible( true ); + + $this->assertTrue( $method->invoke( $module_init ) ); + } } From e96eddea0db381d7b34c628d98c0f1af51d9f65c Mon Sep 17 00:00:00 2001 From: Daryll Doyle Date: Thu, 13 Nov 2025 16:58:25 +0000 Subject: [PATCH 3/5] Update docs --- docs/Modules-and-Initialization.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Modules-and-Initialization.md b/docs/Modules-and-Initialization.md index 490e85e..e00a34d 100644 --- a/docs/Modules-and-Initialization.md +++ b/docs/Modules-and-Initialization.md @@ -40,6 +40,7 @@ Environment cache behavior - When it’s used: only in `production` and `staging` environment types (`wp_get_environment_type()`). - How to clear: delete the `class-loader-cache` folder; it will be rebuilt on next discovery. - How to disable in development: use `development` or `local` environment types, or define `VIP_GO_APP_ENVIRONMENT` to skip the cache. +- How to disable for hosts that don't support file-based caching: `define( 'TENUP_FRAMEWORK_DISABLE_CLASS_CACHE', true );` to skip caching altogether. Hooks - Action: `tenup_framework_module_init__{slug}` — fires before each module’s `register()` runs. From d612e517b1a72b13f24fadc16b09310d9139d770 Mon Sep 17 00:00:00 2001 From: Daryll Doyle Date: Thu, 13 Nov 2025 17:01:56 +0000 Subject: [PATCH 4/5] Linting fixes --- tests/ModuleInitializationTest.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/ModuleInitializationTest.php b/tests/ModuleInitializationTest.php index 6a38bdb..2984b67 100644 --- a/tests/ModuleInitializationTest.php +++ b/tests/ModuleInitializationTest.php @@ -158,8 +158,8 @@ public function testIsClassFullyLoadable() { public function test_should_use_cache_returns_false_when_vip_env_is_defined() { define( 'VIP_GO_APP_ENVIRONMENT', true ); $module_init = \TenupFramework\ModuleInitialization::instance(); - $reflection = new \ReflectionClass( $module_init ); - $method = $reflection->getMethod( 'should_use_cache' ); + $reflection = new \ReflectionClass( $module_init ); + $method = $reflection->getMethod( 'should_use_cache' ); $method->setAccessible( true ); $this->assertFalse( $method->invoke( $module_init ) ); @@ -173,13 +173,13 @@ public function test_should_use_cache_returns_false_when_vip_env_is_defined() { public function test_should_use_cache_returns_false_in_non_production_or_staging_env() { stubs( [ - 'wp_get_environment_type' => 'development' + 'wp_get_environment_type' => 'development', ] ); $module_init = \TenupFramework\ModuleInitialization::instance(); - $reflection = new \ReflectionClass( $module_init ); - $method = $reflection->getMethod( 'should_use_cache' ); + $reflection = new \ReflectionClass( $module_init ); + $method = $reflection->getMethod( 'should_use_cache' ); $method->setAccessible( true ); $this->assertFalse( $method->invoke( $module_init ) ); @@ -193,8 +193,8 @@ public function test_should_use_cache_returns_false_in_non_production_or_staging public function test_should_use_cache_returns_false_when_disable_class_cache_is_defined() { define( 'TENUP_FRAMEWORK_DISABLE_CLASS_CACHE', true ); $module_init = \TenupFramework\ModuleInitialization::instance(); - $reflection = new \ReflectionClass( $module_init ); - $method = $reflection->getMethod( 'should_use_cache' ); + $reflection = new \ReflectionClass( $module_init ); + $method = $reflection->getMethod( 'should_use_cache' ); $method->setAccessible( true ); $this->assertFalse( $method->invoke( $module_init ) ); @@ -208,13 +208,13 @@ public function test_should_use_cache_returns_false_when_disable_class_cache_is_ public function test_should_use_cache_returns_true_under_default_conditions() { stubs( [ - 'wp_get_environment_type' => 'production' + 'wp_get_environment_type' => 'production', ] ); $module_init = \TenupFramework\ModuleInitialization::instance(); - $reflection = new \ReflectionClass( $module_init ); - $method = $reflection->getMethod( 'should_use_cache' ); + $reflection = new \ReflectionClass( $module_init ); + $method = $reflection->getMethod( 'should_use_cache' ); $method->setAccessible( true ); $this->assertTrue( $method->invoke( $module_init ) ); From ea9349f5d50d306126714123ece5d6d09dd38f67 Mon Sep 17 00:00:00 2001 From: Daryll Doyle Date: Thu, 13 Nov 2025 17:04:44 +0000 Subject: [PATCH 5/5] Update docs --- docs/Autoloading.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Autoloading.md b/docs/Autoloading.md index af8b51c..0b7038d 100644 --- a/docs/Autoloading.md +++ b/docs/Autoloading.md @@ -82,7 +82,7 @@ Environment caching: - Discovery results are cached only in production and staging environments (per `wp_get_environment_type()`). - Cache is stored under the directory you pass to `init_classes()`, in a "class-loader-cache" folder (e.g., `YOUR_PLUGIN_INC . 'class-loader-cache'`). - To refresh: delete that folder; it will be rebuilt automatically. -- Caching is skipped entirely when the constant `VIP_GO_APP_ENVIRONMENT` is defined. +- Caching is skipped entirely when the constant `VIP_GO_APP_ENVIRONMENT` is defined or when `TENUP_FRAMEWORK_DISABLE_CLASS_CACHE` is set to `true`. Use `define( 'TENUP_FRAMEWORK_DISABLE_CLASS_CACHE', true )` in environments that don't support writable file systems. ## Defining a Module ```php