(D8+) Strange handling of `$initialized` leads to crash in civix
Steps to Reproduce
Create a site running D9/D10. (I focused my triage on D10, but the same arises on D9, and I suspect it would affect D8.)
Then:
cd web/sites/default/files/civicrm/ext/civicrm
wget https://download.civicrm.org/civix/civix-23.08.0.phar -O civix.phar
php ./civix.phar generate:module foobar
## Answer "Y" to question about enabling the extension
It crashes with:
TypeError: htmlentities(): Argument #1 ($string) must be of type string, array given in /home/totten/bknix/build/d10/vendor/civicrm/civicrm-core/CRM/Utils/System.php on line 284 #0 /home/totten/bknix/build/d10/vendor/civicrm/civicrm-core/CRM/Utils/System.php(284): htmlentities(Array)
#1 /home/totten/bknix/build/d10/vendor/civicrm/civicrm-core/CRM/Core/Menu.php(445): CRM_Utils_System::url('civicrm/tag', 'reset=1', false, NULL, true, false, true)
#2 /home/totten/bknix/build/d10/vendor/civicrm/civicrm-core/CRM/Core/Menu.php(265): CRM_Core_Menu::buildBreadcrumb(Array, 'civicrm/tag/edi...')
#3 /home/totten/bknix/build/d10/vendor/civicrm/civicrm-core/CRM/Core/Menu.php(296): CRM_Core_Menu::build(Array)
#4 /home/totten/bknix/build/d10/vendor/civicrm/civicrm-core/CRM/Core/Invoke.php(389): CRM_Core_Menu::store()
#5 /home/totten/bknix/build/d10/vendor/civicrm/civicrm-core/CRM/Extension/Manager.php(319): CRM_Core_Invoke::rebuildMenuAndCaches(true)
#6 /home/totten/bknix/build/d10/vendor/civicrm/civicrm-core/api/v3/Extension.php(42): CRM_Extension_Manager->install(Array)
Analysis
- The apparent error stems from
\CRM_Utils_System_Drupal8->url()
. It swallows an exception and returns a malformed$url
instead. The malformed$url
is not astring
and cannot be handled byhtmlentities()
. - The underlying exception is raised by
\Drupal\civicrm\Civicrm->initialize()
. It tries to loadcivicrm.settings.php
and fails. - In the big picture, the underlying exception makes no sense. Look at the callstack: CiviCRM is already running. The
civicrm.settings.php
has already been loaded. The file exists. -
Why are we initializing again? Because CivicrmPathProcessor repeatedly creates new instances of
Drupal\civicrm\Civicrm
. This negates the$initialized
guard.- To visualize this, you can apply https://gist.github.com/totten/e983d23439addeb7f76b0d7f52679031 and run
cv flush
.
- To visualize this, you can apply https://gist.github.com/totten/e983d23439addeb7f76b0d7f52679031 and run
-
Why is the file missing? The CWD changed.
- In the original CLI, the CWD is
DRUPALSITE/web/sites/default/files/civicrm/ext/civicrm
- During bootstrap, CWD changes to the web-root (
DRUPALSITE/web
). The chosen path for$settingsFile
is relative to that. - But
civix
needs to create files in the original CWD. After bootstrap, it returns to the original CWD. - But
$settingsFile
is relative -- and not valid in this new path.
- In the original CLI, the CWD is