Migrate CivicrmHelper::parseUrl() to CRM_Utils_System_Drupal8::parseUrl(). Resolve...
authorTim Otten <totten@civicrm.org>
Mon, 1 Jul 2019 23:58:58 +0000 (16:58 -0700)
committerTim Otten <totten@civicrm.org>
Tue, 2 Jul 2019 00:20:31 +0000 (17:20 -0700)
commite7e176259f89af7fdda0a2940171d313f98f678f
tree84e7c293863a925f9fa22fb65e3249341dc78ca0
parentddd387f5009a3a9a340ec4f3a06ed86ba2515131
Migrate CivicrmHelper::parseUrl() to CRM_Utils_System_Drupal8::parseUrl(). Resolve dep order.

This fixes a bug which manifests during CLI installation. It corrects a dependency issue by
migrating an install-critical function from `civicrm-drupal-8` to `civicrm-core`.

Before
------

Consider this sequence from `cv core:install` docs. (For simplicity/legibility, the example
is minimalist.)

```
$ cv core:install --cms-base-url=http://example.com/
$ drush -y en civicrm
```

The first step crashes. Partial console output:

```
[bknix-dfl:~/bknix/build/d8prj-re] cv core:install -f --cms-base-url=http://d8prj-re.bknix:8001 -m 'settings.userFrameworkResourceURL=[cms.root]/libraries/civicrm' -v
Found code for civicrm-core in /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core
Found code for civicrm-setup in /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-setup
Found existing civicrm.settings.php in /Users/myuser/bknix/build/d8prj-re/web/sites/default
Removing civicrm.settings.php from /Users/myuser/bknix/build/d8prj-re/web/sites/default
Creating civicrm.settings.php in /Users/myuser/bknix/build/d8prj-re/web/sites/default
Found existing civicrm_* database tables in d8prjrecms_rwlck
Removing civicrm_* database tables in d8prjrecms_rwlck
Creating civicrm_* database tables in d8prjrecms_rwlck

  [Symfony\Component\Debug\Exception\FatalThrowableError]
  Class 'Drupal\civicrm\CivicrmHelper' not found

Exception trace:
 () at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/CRM/Utils/System/Drupal8.php:303
 CRM_Utils_System_Drupal8->url() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/CRM/Utils/System.php:295
 CRM_Utils_System::url() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/CRM/Core/Menu.php:581
 CRM_Core_Menu::buildBreadcrumb() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/CRM/Core/Menu.php:281
 CRM_Core_Menu::build() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/CRM/Core/Menu.php:308
 CRM_Core_Menu::store() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/CRM/Core/Invoke.php:373
 CRM_Core_Invoke::rebuildMenuAndCaches() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/api/v3/System.php:49
 civicrm_api3_system_flush() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/Civi/API/Provider/MagicFunctionProvider.php:101
 Civi\API\Provider\MagicFunctionProvider->invoke() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/Civi/API/Kernel.php:168
 Civi\API\Kernel->runRequest() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/Civi/API/Kernel.php:99
 Civi\API\Kernel->runSafe() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/api/api.php:23
 civicrm_api() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/Civi/Core/DatabaseInitializer.php:50
 Civi\Core\DatabaseInitializer::initialize() at /Users/myuser/bknix/build/d8prj-re/vendor/symfony/event-dispatcher/EventDispatcher.php:212
 Symfony\Component\EventDispatcher\EventDispatcher->doDispatch() at /Users/myuser/bknix/build/d8prj-re/vendor/symfony/event-dispatcher/EventDispatcher.php:44
 Symfony\Component\EventDispatcher\EventDispatcher->dispatch() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/Civi/Core/CiviEventDispatcher.php:47
 Civi\Core\CiviEventDispatcher->dispatch() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/CRM/Core/Config.php:572
 CRM_Core_Config->handleFirstRun() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/CRM/Core/Config.php:128
 CRM_Core_Config::singleton() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/packages/DB/DataObject.php:2304
 DB_DataObject->_connect() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/CRM/Core/DAO.php:474
 CRM_Core_DAO->initialize() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/CRM/Core/DAO.php:126
 CRM_Core_DAO->__construct() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/CRM/Core/DAO.php:1488
 CRM_Core_DAO::singleValueQuery() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/CRM/Utils/SQL.php:67
 CRM_Utils_SQL::getSqlModes() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/CRM/Core/DAO.php:168
 CRM_Core_DAO::init() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-core/Civi/Core/Container.php:494
 Civi\Core\Container::boot() at /Users/myuser/bknix/build/d8prj-re/vendor/civicrm/civicrm-setup/plugins/installDatabase/InstallSchema.civi-setup.php:94
 InstallSchemaPlugin->installDatabase() at /Users/myuser/bknix/build/d8prj-re/vendor/symfony/event-dispatcher/EventDispatcher.php:212
 ...
```

In English: towards the end of the `core:install`, it boots up Civi for the
first time, which causes a general system flush, a menu rebuild, and some
calls to `url()` and `CivirmHelper`.  But the `civicrm-drupal-8` module
isn't online yet, so `CivicrmHelper` isn't isn't available yet.

After
-----

That crash does not happen. The install routine is able to run with or without `civicrm-drupal-8` active.

Technical Details
-----------------

This is one of two changes.  (The first adds the function to `civicrm-core`;
the second removes it from `civicrm-drupal-8`.)

You might wonder: Will this be a flip-floppy problem?  Perhaps there's some
dataflow through `drupal/core`and `civicrm-drupal-8/src/Routing/Routes.php`
where the new call to `CRM_Core_Config::singleton()->userSystem->parseUrl()`
cannot be processed because `civicrm-core` isn't available yet?

This hypothetical can be dispensed by reading `src/Routing/Routes.php`
(either old code or new code).  The function already begins with
`\Drupal::service('civicrm')->initialize();`, which boots all the core Civi
services (like `CRM_Core_Config::singleton()->userSystem`).  The system is
already online before the relevant code is called.
CRM/Utils/System/Drupal8.php