From 5f16ea7b5b1d4edcd4be21bf7963dafead9686ea Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Wed, 1 Apr 2020 01:00:07 -0700 Subject: [PATCH] dev/core#1674 - Update container cache when folder is removed or created Conceptually, you want to: * (A) Keep the container cache when nothing has changed (regardless of whether that status-quo has an API4 subscriber folder). * (B) Update the cache if Civi/Api4/Event/Subscriber/*.php has been newly created * (C) Update the cache if Civi/Api4/Event/Subscriber/*.php has been newly removed To test this out, I hacked `Civi\Core\Container::loadContainer()` to emit a debug message to indicate if it is reusing the cache or updating. Then, I prepared two terminals for running alternate steps: * In terminal 1, go back and forth with adding/removing folders/files like `Civi/Api4/Event/Subscriber`. * In terminal 2, periodically run `cv ev 'echo "Hello\n";'` and note whether the cache is update. In this way, we can see if a developer action (adding a file) leads to an automatic update in the cache. I found that the previous commit fixed (A) and did (C), but it failed to update per (B). This commit should handle (A), (B), and (C). --- CRM/Api4/Services.php | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/CRM/Api4/Services.php b/CRM/Api4/Services.php index c00487df5f..fba89627dd 100644 --- a/CRM/Api4/Services.php +++ b/CRM/Api4/Services.php @@ -81,9 +81,14 @@ class CRM_Api4_Services { ); foreach ($locations as $location) { $path = \CRM_Utils_File::addTrailingSlash(dirname($location)) . str_replace('\\', DIRECTORY_SEPARATOR, $namespace); + if (!file_exists($path) || !is_dir($path)) { + $resource = new \Symfony\Component\Config\Resource\FileExistenceResource($path); + $container->addResource($resource); + continue; + } + try { $resource = new \Symfony\Component\Config\Resource\DirectoryResource($path, ';\.php$;'); - $addResource = FALSE; foreach (glob("$path*.php") as $file) { $matches = []; preg_match('/(\w*)\.php$/', $file, $matches); @@ -92,15 +97,18 @@ class CRM_Api4_Services { if ($serviceClass->isInstantiable()) { $definition = $container->register(str_replace('\\', '_', $serviceName), $serviceName); $definition->addTag($tag); - $addResource = TRUE; } } - if ($addResource) { - $container->addResource($resource); - } + $container->addResource($resource); } catch (\InvalidArgumentException $e) { //Directory is not found so lets not do anything i suppose. + + // FIXME: The above comment implies that the try/catch is specifically + // about the directory's existence, which would make it redundant with the + // newer "file_exists()" guard. However, the actual "catch()" seems broader, + // and I don't see anything in DirectoryResource that throws the exception. + // So... maybe it's not needed, or maybe there's some additional purpose. } } } -- 2.25.1