vendor/doctrine/doctrine-bundle/ConnectionFactory.php line 53

Open in your IDE?
  1. <?php
  2. namespace Doctrine\Bundle\DoctrineBundle;
  3. use Doctrine\Common\EventManager;
  4. use Doctrine\DBAL\Configuration;
  5. use Doctrine\DBAL\Connection;
  6. use Doctrine\DBAL\DriverManager;
  7. use Doctrine\DBAL\Exception as DBALException;
  8. use Doctrine\DBAL\Exception\DriverException;
  9. use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
  10. use Doctrine\DBAL\Platforms\AbstractPlatform;
  11. use Doctrine\DBAL\Types\Type;
  12. use Doctrine\Deprecations\Deprecation;
  13. use function array_merge;
  14. use function is_subclass_of;
  15. use function trigger_deprecation;
  16. use const PHP_EOL;
  17. /** @psalm-import-type Params from DriverManager */
  18. class ConnectionFactory
  19. {
  20.     /** @var mixed[][] */
  21.     private array $typesConfig = [];
  22.     private bool $initialized false;
  23.     /** @param mixed[][] $typesConfig */
  24.     public function __construct(array $typesConfig)
  25.     {
  26.         $this->typesConfig $typesConfig;
  27.     }
  28.     /**
  29.      * Create a connection by name.
  30.      *
  31.      * @param mixed[]               $params
  32.      * @param array<string, string> $mappingTypes
  33.      * @psalm-param Params $params
  34.      *
  35.      * @return Connection
  36.      */
  37.     public function createConnection(array $params, ?Configuration $config null, ?EventManager $eventManager null, array $mappingTypes = [])
  38.     {
  39.         if (! $this->initialized) {
  40.             $this->initializeTypes();
  41.         }
  42.         $overriddenOptions = [];
  43.         if (isset($params['connection_override_options'])) {
  44.             trigger_deprecation('doctrine/doctrine-bundle''2.4''The "connection_override_options" connection parameter is deprecated');
  45.             $overriddenOptions $params['connection_override_options'];
  46.             unset($params['connection_override_options']);
  47.         }
  48.         if (! isset($params['pdo']) && (! isset($params['charset']) || $overriddenOptions || isset($params['dbname_suffix']))) {
  49.             $wrapperClass null;
  50.             if (isset($params['wrapperClass'])) {
  51.                 if (! is_subclass_of($params['wrapperClass'], Connection::class)) {
  52.                     throw DBALException::invalidWrapperClass($params['wrapperClass']);
  53.                 }
  54.                 $wrapperClass           $params['wrapperClass'];
  55.                 $params['wrapperClass'] = null;
  56.             }
  57.             $connection DriverManager::getConnection($params$config$eventManager);
  58.             $params     $this->addDatabaseSuffix(array_merge($connection->getParams(), $overriddenOptions));
  59.             $driver     $connection->getDriver();
  60.             $platform   $driver->getDatabasePlatform();
  61.             if (! isset($params['charset'])) {
  62.                 if ($platform instanceof AbstractMySQLPlatform) {
  63.                     $params['charset'] = 'utf8mb4';
  64.                     if (isset($params['defaultTableOptions']['collate'])) {
  65.                         Deprecation::trigger(
  66.                             'doctrine/doctrine-bundle',
  67.                             'https://github.com/doctrine/dbal/issues/5214',
  68.                             'The "collate" default table option is deprecated in favor of "collation" and will be removed in doctrine/doctrine-bundle 3.0. '
  69.                         );
  70.                         $params['defaultTableOptions']['collation'] = $params['defaultTableOptions']['collate'];
  71.                         unset($params['defaultTableOptions']['collate']);
  72.                     }
  73.                     if (! isset($params['defaultTableOptions']['collation'])) {
  74.                         $params['defaultTableOptions']['collation'] = 'utf8mb4_unicode_ci';
  75.                     }
  76.                 } else {
  77.                     $params['charset'] = 'utf8';
  78.                 }
  79.             }
  80.             if ($wrapperClass !== null) {
  81.                 $params['wrapperClass'] = $wrapperClass;
  82.             } else {
  83.                 $wrapperClass Connection::class;
  84.             }
  85.             $connection = new $wrapperClass($params$driver$config$eventManager);
  86.         } else {
  87.             $connection DriverManager::getConnection($params$config$eventManager);
  88.         }
  89.         if (! empty($mappingTypes)) {
  90.             $platform $this->getDatabasePlatform($connection);
  91.             foreach ($mappingTypes as $dbType => $doctrineType) {
  92.                 $platform->registerDoctrineTypeMapping($dbType$doctrineType);
  93.             }
  94.         }
  95.         return $connection;
  96.     }
  97.     /**
  98.      * Try to get the database platform.
  99.      *
  100.      * This could fail if types should be registered to an predefined/unused connection
  101.      * and the platform version is unknown.
  102.      *
  103.      * @link https://github.com/doctrine/DoctrineBundle/issues/673
  104.      *
  105.      * @throws DBALException
  106.      */
  107.     private function getDatabasePlatform(Connection $connection): AbstractPlatform
  108.     {
  109.         try {
  110.             return $connection->getDatabasePlatform();
  111.         } catch (DriverException $driverException) {
  112.             throw new DBALException(
  113.                 'An exception occurred while establishing a connection to figure out your platform version.' PHP_EOL .
  114.                 "You can circumvent this by setting a 'server_version' configuration value" PHP_EOL PHP_EOL .
  115.                 'For further information have a look at:' PHP_EOL .
  116.                 'https://github.com/doctrine/DoctrineBundle/issues/673',
  117.                 0,
  118.                 $driverException
  119.             );
  120.         }
  121.     }
  122.     /**
  123.      * initialize the types
  124.      */
  125.     private function initializeTypes(): void
  126.     {
  127.         foreach ($this->typesConfig as $typeName => $typeConfig) {
  128.             if (Type::hasType($typeName)) {
  129.                 Type::overrideType($typeName$typeConfig['class']);
  130.             } else {
  131.                 Type::addType($typeName$typeConfig['class']);
  132.             }
  133.         }
  134.         $this->initialized true;
  135.     }
  136.     /**
  137.      * @param array<string, mixed> $params
  138.      *
  139.      * @return array<string, mixed>
  140.      */
  141.     private function addDatabaseSuffix(array $params): array
  142.     {
  143.         if (isset($params['dbname']) && isset($params['dbname_suffix'])) {
  144.             $params['dbname'] .= $params['dbname_suffix'];
  145.         }
  146.         foreach ($params['replica'] ?? [] as $key => $replicaParams) {
  147.             if (! isset($replicaParams['dbname'], $replicaParams['dbname_suffix'])) {
  148.                 continue;
  149.             }
  150.             $params['replica'][$key]['dbname'] .= $replicaParams['dbname_suffix'];
  151.         }
  152.         if (isset($params['primary']['dbname'], $params['primary']['dbname_suffix'])) {
  153.             $params['primary']['dbname'] .= $params['primary']['dbname_suffix'];
  154.         }
  155.         return $params;
  156.     }
  157. }