OK, analyze:
We miss a call to ->sql_pconnect()
or ->connectDB()
in Install Tool somehow because this call will properly instantiate the ->handlerInstance
and thus lead to have the _DEFAULT instance uninitialized.
This missing call is originating from
\TYPO3\CMS\Core\Core\Bootstrap::initializeTypo3DbGlobal()
which is called from
\TYPO3\CMS\Install\Controller\Action\AbstractAction::loadExtLocalconfDatabaseAndExtTables()
Now, within DBAL's method sql_select_db()
, we miss the check of ->isConnected()
at the beginning, something that we have when using Core's overridden method.
If we add the call:
if (!$this->isConnected()) {
$this->connectDB();
}
we have a recursion to ->sql_select_db()
because \TYPO3\CMS\Dbal\Database\DatabaseConnection::isConnected()
returns FALSE since $this->lastHandlerKey
is still to its default (empty) value (see class definition).
BUT, if we set the default value to "_DEFAULT", this fixes the bug, if we are already in the main windows of the Install Tool (initial steps have passed) but it crashes the Install Tool with:
TYPO3 Fatal Error: No database selected!
when opening the Install Tool for the first time, e.g., by clicking the corresponding module in TYPO3 Backend.
This is caused by \TYPO3\CMS\Dbal\Database\DatabaseConnection::handler_init()
not fully initializing $this->handlerCfg[$handlerKey]
(beginning of the method). More specifically the 'type' is still set to "native", which only works if DBAL is configured with a 'mysqli' backend, so not in a real use of DBAL (e.g., with MSSQL).
This in turn, happens because prior to the change, DBAL's sql_select_db()
did not call ->connectDB()
. But not having this call causes another bug in Install Tool, namely that opening http://mywebsite/typo3/install
always blocks on the database selection (call to getDatabaseList()
which calls ->admin_get_dbs()
, again as "native" driver has not been replaced. Only (current) way is to manually trick the URL to go to the Tool controller.
Dirty hack¶
Merge "type" and "driverOptions" when initializing ->handlerCfg['__DEFAULT']
from $this->conf
when $this->databaseName
is not empty:
$this->handlerCfg[$handlerKey]['type'] = $this->conf['handlerCfg'][$handlerKey]['type'];
// same for driverOptions