contao / core-bundle

[READ-ONLY] Contao Core Bundle
GNU Lesser General Public License v3.0
123 stars 58 forks source link

No database selected during /contao/install when using download archive #736

Closed fritzmg closed 7 years ago

fritzmg commented 7 years ago
  1. Download the Contao Managed Edition 4.3.7 from contao.org
  2. Extract and run /contao/install.
  3. Accept the license.

On the subsequent screens (entering the install tool password plus entering the database details) the following error message will be displayed at the bottom of the page:

Fatal error: Uncaught PDOException: SQLSTATE[3D000]: Invalid catalog name: 1046 No database selected in \vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php:104 
Stack trace: 
#0 \vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOConnection.php(104): PDO->query('SHOW FULL TABLE...') 
#1 \vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php(852): Doctrine\DBAL\Driver\PDOConnection->query('SHOW FULL TABLE...') 
#2 \vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php(785): Doctrine\DBAL\Connection->executeQuery('SHOW FULL TABLE...', Array, Array) 
#3 \vendor\doctrine\dbal\lib\Doctrine\DBAL\Schema\AbstractSchemaManager.php(219): Doctrine\DBAL\Connection->fetchAll('SHOW FULL TABLE...') 
#4 \vendor\doctrine\dbal\lib\Doctrine\DBAL\Schema\AbstractSchemaManager.php(207): Doctrine\DBAL\Schema\AbstractSchemaManager->listTableNames() 
#5 \vendor\contao\core-bundle\src\EventListener\ in \vendor\symfony\symfony\src\Symfony\Component\HttpKernel\HttpKernel.php on line 99

Testing environment:

Not sure if this ticket belongs to the core-bundle, the installation-bundle or the managed-edition. The error only seems to happen with the managed edition during installation and the error is genereated within the EventListener of the core-bundle.

The error message is appended after the </html> from the install tool.

leofeyer commented 7 years ago

I cannot reproduce the issue and it has not occurred at my presentation on the Contao Nordtag, either.

fritzmg commented 7 years ago

Yeah haven't seen any other reports yet either. May be it is Windows specific, I'll try to debug.

fritzmg commented 7 years ago

The error happens here:

    /**
     * Checks whether the controller can be run.
     *
     * @return bool
     */
    private function canRunController()
    {
        /** @var Config $config */
        $config = $this->framework->getAdapter(Config::class);
        return $config->isComplete()
            && !$config->get('disableCron')
            && $this->connection->getSchemaManager()->tablesExist(['tl_cron'])
        ;
    }

https://github.com/contao/core-bundle/blob/4.3.7/src/EventListener/CommandSchedulerListener.php#L73

The CommandSchedulerListener is querying a table - but that won't be possible during /contao/install if the database connection has not been set up yet.

@leofeyer how did you test? This problem only occurs if you download Contao from contao.org (and it needs to be a fresh installation). It won't occur with composer create-project, since the database connection will be set up during that process.

leofeyer commented 7 years ago

This has been fixed in e5527fba48d30ced12cdc880907130dce6015bcc already.

fritzmg commented 7 years ago

This is still happening in Contao 4.3.8 (Managed Edition downloaded from contao.org).

screen shot 2017-04-25 at 09 23 00

fritzmg commented 7 years ago
$this->connection->isConnected()

returns true, even though no database connection is present.

fritzmg commented 7 years ago

Doctrine\DBAL\Connection::isConnected returns

/**
 * Whether an actual connection to the database is established.
 *
 * @return boolean
 */
public function isConnected()
{
    return $this->_isConnected;
}

https://github.com/doctrine/dbal/blob/v2.5.12/lib/Doctrine/DBAL/Connection.php#L551

and this variable will be set to true here:

$this->_conn = $this->_driver->connect($this->_params, $user, $password, $driverOptions);
$this->_isConnected = true;

https://github.com/doctrine/dbal/blob/v2.5.12/lib/Doctrine/DBAL/Connection.php#L361

I am guessing that a connection can already be established with these default parameters:

parameters:
    database_host: localhost
    database_port: ~
    database_user: ~
    database_password: ~
    database_name: ~

# Doctrine configuration
doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver: pdo_mysql
                host: "%database_host%"
                port: "%database_port%"
                user: "%database_user%"
                password: "%database_password%"
                dbname: "%database_name%"
                charset: UTF8

https://github.com/contao/manager-bundle/blob/4.3.8/src/Resources/contao-manager/doctrine.yml

However, you are of course not able to do anything with that connection (due to the missing, username, password and database name).

fritzmg commented 7 years ago

I am guessing this happens under the following circumstances:

leofeyer commented 7 years ago

That's a server misconfiguration IMHO.

fritzmg commented 7 years ago

Yeah, I am assuming it's just something XAMPP does by default, I am not sure though.

fritzmg commented 7 years ago

According to the MySQL documentation these anonymous accounts are created by default - but it advises you to remove them: https://dev.mysql.com/doc/refman/5.7/en/default-privileges.html

fritzmg commented 7 years ago

A related problem happens when you install an extension that has TL_CRON entries defined (e.g. notification_center). When opening the install tool after installation, you might see something like

Fatal error: Uncaught PDOException: SQLSTATE[42S02]: Base table or view not found:
1146 Table 'contao4.tl_nc_gateway' doesn't exist in …

at the bottom of the install tool for example, before the database is updated.

May be the front end cron should not be integrated into the install tool at all.

leofeyer commented 7 years ago

The command scheduler checks if there is a database connection and if the tables have been created: https://github.com/contao/core-bundle/blob/release/4.4.0/src/EventListener/CommandSchedulerListener.php#L71-L75

fritzmg commented 7 years ago

The command scheduler checks if there is a database connection and if the tables have been created: https://github.com/contao/core-bundle/blob/release/4.4.0/src/EventListener/CommandSchedulerListener.php#L71-L75

It only checks for tl_cron. If you install an extension which registers a TL_CRON hook and has its own database tables or fields and in that hook the extension accesses these tables or fields, you will get a fatal error at the bottom of the install tool, because the command scheduler is executed there.

Imho the command scheduler should net get executed at all by the install tool.

leofeyer commented 7 years ago

Then those extensions are not set up correctly, because they don't check if their tables exist.

fritzmg commented 7 years ago

Then those extensions are not set up correctly, because they don't check if their tables exist.

Hm, is an extension supposed to check for their tables and fields in every hook?

leofeyer commented 7 years ago

Of course. The install tool triggers a bunch of hooks and if you subscribe to one of it and want to access the database, you should check if it exists.

fritzmg commented 7 years ago

The install tool triggers a bunch of hooks and if you subscribe to one of it and want to access the database, you should check if it exists.

Yes, though in the past the command scheduler was not executed within the install tool, thus it was safe to register TL_CRON hooks that require a properly updated database. May be this should be added to the UPGRADE.md.

fritzmg commented 7 years ago

This change was introduced in Contao 4.1.0 as far as I can see. Previously there was no CommandSchedulerListener on the onKernelTerminate event.

aschempp commented 7 years ago

see https://github.com/contao/installation-bundle/issues/54

leofeyer commented 7 years ago

Changed in fd3613159ba9a2ce710f5f0f38495661c055a670.