TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
ConnectionPool.php
Go to the documentation of this file.
1 <?php
2 declare(strict_types=1);
3 namespace TYPO3\CMS\Core\Database;
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
18 use Doctrine\DBAL\Configuration;
19 use Doctrine\DBAL\DriverManager;
20 use Doctrine\DBAL\Events;
21 use Doctrine\DBAL\Types\Type;
28 
40 {
44  const DEFAULT_CONNECTION_NAME = 'Default';
45 
49  protected static $connections = [];
50 
54  protected $customDoctrineTypes = [
55  EnumType::TYPE => EnumType::class,
56  SetType::TYPE => SetType::class,
57  ];
58 
68  public function getConnectionForTable(string $tableName): Connection
69  {
70  if (empty($tableName)) {
71  throw new \UnexpectedValueException(
72  'ConnectionPool->getConnectionForTable() requires a table name to be provided.',
73  1459421719
74  );
75  }
76 
77  $connectionName = self::DEFAULT_CONNECTION_NAME;
78  if (!empty($GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping'][$tableName])) {
79  $connectionName = (string)$GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping'][$tableName];
80  }
81 
82  return $this->getConnectionByName($connectionName);
83  }
84 
96  public function getConnectionByName(string $connectionName): Connection
97  {
98  if (empty($connectionName)) {
99  throw new \UnexpectedValueException(
100  'ConnectionPool->getConnectionByName() requires a connection name to be provided.',
101  1459422125
102  );
103  }
104 
105  if (isset(static::$connections[$connectionName])) {
106  return static::$connections[$connectionName];
107  }
108 
109  if (empty($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][$connectionName])
110  || !is_array($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][$connectionName])
111  ) {
112  throw new \RuntimeException(
113  'The requested database connection named "' . $connectionName . '" has not been configured.',
114  1459422492
115  );
116  }
117 
118  $connectionParams = $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][$connectionName];
119  if (empty($connectionParams['wrapperClass'])) {
120  $connectionParams['wrapperClass'] = Connection::class;
121  }
122 
123  if (!is_a($connectionParams['wrapperClass'], Connection::class, true)) {
124  throw new \UnexpectedValueException(
125  'The "wrapperClass" for the connection name "' . $connectionName .
126  '" needs to be a subclass of "' . Connection::class . '".',
127  1459422968
128  );
129  }
130 
131  static::$connections[$connectionName] = $this->getDatabaseConnection($connectionParams);
132 
133  return static::$connections[$connectionName];
134  }
135 
142  protected function getDatabaseConnection(array $connectionParams): Connection
143  {
144  // Default to UTF-8 connection charset
145  if (empty($connectionParams['charset'])) {
146  $connectionParams['charset'] = 'utf-8';
147  }
148 
150  $conn = DriverManager::getConnection($connectionParams);
151  $conn->setFetchMode(\PDO::FETCH_ASSOC);
152  $conn->prepareConnection($connectionParams['initCommands'] ?? '');
153 
154  // Register custom data types
155  foreach ($this->customDoctrineTypes as $type => $className) {
156  if (!Type::hasType($type)) {
157  Type::addType($type, $className);
158  }
159  }
160 
161  // Register all custom data types in the type mapping
162  foreach ($this->customDoctrineTypes as $type => $className) {
163  $conn->getDatabasePlatform()->registerDoctrineTypeMapping($type, $type);
164  }
165 
166  // Handler for building custom data type column definitions
167  // in the SchemaManager
168  $conn->getDatabasePlatform()->getEventManager()->addEventListener(
169  Events::onSchemaColumnDefinition,
170  GeneralUtility::makeInstance(SchemaColumnDefinitionListener::class)
171  );
172 
173  // Handler for adding custom database platform options to ALTER TABLE
174  // requests in the SchemaManager
175  $conn->getDatabasePlatform()->getEventManager()->addEventListener(
176  Events::onSchemaAlterTable,
177  GeneralUtility::makeInstance(SchemaAlterTableListener::class)
178  );
179 
180  return $conn;
181  }
182 
190  public function getQueryBuilderForTable(string $tableName): QueryBuilder
191  {
192  if (empty($tableName)) {
193  throw new \UnexpectedValueException(
194  'ConnectionPool->getQueryBuilderForTable() requires a connection name to be provided.',
195  1459423448
196  );
197  }
198 
199  return $this->getConnectionForTable($tableName)->createQueryBuilder();
200  }
201 
211  public function getConnectionNames(): array
212  {
213  return array_keys($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']);
214  }
215 
225  public function getCustomDoctrineTypes(): array
226  {
228  }
229 }
getConnectionByName(string $connectionName)
if(TYPO3_MODE=== 'BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static makeInstance($className,...$constructorArguments)