You are here

public static function Database::findDriverAutoloadDirectory in Drupal 8

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Database/Database.php \Drupal\Core\Database\Database::findDriverAutoloadDirectory()

Finds the directory to add to the autoloader for the driver's namespace.

For Drupal sites that manage their codebase with Composer, the package that provides the database driver should add the driver's namespace to Composer's autoloader. However, to support sites that add Drupal modules without Composer, and because the database connection must be established before Drupal adds the module's entire namespace to the autoloader, the database connection info array can include an "autoload" key containing the autoload directory for the driver's namespace. For requests that connect to the database via a connection info array, the value of the "autoload" key is automatically added to the autoloader.

This method can be called to find the default value of that key when the database connection info array isn't available. This includes:

  • Console commands and test runners that connect to a database specified by a database URL rather than a connection info array.
  • During installation, prior to the connection info array being written to settings.php.

This method returns the directory that must be added to the autoloader for the given namespace.

  • If the namespace is a sub-namespace of a Drupal module, then this method returns the autoload directory for that namespace, allowing Drupal modules containing database drivers to be added to a Drupal website without Composer.
  • If the namespace is a sub-namespace of Drupal\Core or Drupal\Driver, then this method returns FALSE, because Drupal core's autoloader already includes these namespaces, so no additional autoload directory is required for any code within them.
  • If the namespace is anything else, then this method returns FALSE, because neither drupal_get_database_types() nor static::convertDbUrlToConnectionInfo() support that anyway. One can manually edit the connection info array in settings.php to reference any arbitrary namespace, but requests using that would use the corresponding 'autoload' key in that connection info rather than calling this method.

Parameters

string $namespace: The database driver's namespace.

string $root: The root directory of the Drupal installation.

Return value

string|false The PSR-4 directory to add to the autoloader for the namespace if the namespace is a sub-namespace of a Drupal module. FALSE otherwise, as explained above.

Throws

\RuntimeException Exception thrown when a module provided database driver does not exist.

6 calls to Database::findDriverAutoloadDirectory()
Database::convertDbUrlToConnectionInfo in core/lib/Drupal/Core/Database/Database.php
Converts a URL to a database connection info array.
DatabaseTest::testFindDriverAutoloadDirectory in core/tests/Drupal/Tests/Core/Database/DatabaseTest.php
@covers ::findDriverAutoloadDirectory @dataProvider providerFindDriverAutoloadDirectory
DatabaseTest::testFindDriverAutoloadDirectoryException in core/tests/Drupal/Tests/Core/Database/DatabaseTest.php
@covers ::findDriverAutoloadDirectory @dataProvider providerFindDriverAutoloadDirectoryException
DatabaseVersionCheckUpdateTest::testUpdate in core/modules/system/tests/src/Functional/Update/DatabaseVersionCheckUpdateTest.php
Tests that updates fail if the database does not meet the minimum version.
InstallerExistingBrokenDatabaseSettingsTest::prepareEnvironment in core/tests/Drupal/FunctionalTests/Installer/InstallerExistingBrokenDatabaseSettingsTest.php
Prepares the current environment for running the test.

... See full list

File

core/lib/Drupal/Core/Database/Database.php, line 563

Class

Database
Primary front-controller for the database system.

Namespace

Drupal\Core\Database

Code

public static function findDriverAutoloadDirectory($namespace, $root) {

  // As explained by this method's documentation, return FALSE if the
  // namespace is not a sub-namespace of a Drupal module.
  if (!static::isWithinModuleNamespace($namespace)) {
    return FALSE;
  }

  // Extract the module information from the namespace.
  list(, $module, $module_relative_namespace) = explode('\\', $namespace, 3);

  // The namespace is within a Drupal module. Find the directory where the
  // module is located.
  $extension_discovery = new ExtensionDiscovery($root, FALSE, []);
  $modules = $extension_discovery
    ->scan('module');
  if (!isset($modules[$module])) {
    throw new \RuntimeException(sprintf("Cannot find the module '%s' for the database driver namespace '%s'", $module, $namespace));
  }
  $module_directory = $modules[$module]
    ->getPath();

  // All code within the Drupal\MODULE namespace is expected to follow a
  // PSR-4 layout within the module's "src" directory.
  $driver_directory = $module_directory . '/src/' . str_replace('\\', '/', $module_relative_namespace) . '/';
  if (!is_dir($root . '/' . $driver_directory)) {
    throw new \RuntimeException(sprintf("Cannot find the database driver namespace '%s' in module '%s'", $namespace, $module));
  }
  return $driver_directory;
}