1 install.inc protected DatabaseTasks::connect()

Check if we can connect to the database.

File

core/includes/install.inc, line 436
API functions for installing modules and themes.

Class

DatabaseTasks
Database installer structure.

Code

protected function connect() {
  $original_connection_info = $modified_connection_info = Database::getConnectionInfo();
  $last_exception = FALSE;
  $extra_help = '';

  try {
    // This doesn't actually test the connection.
    db_set_active();
    // Now actually do a check.
    Database::getConnection();
  }
  catch (PDOException $e) {
    $original_failed_exception = $last_exception = $e;
  }

  // Attempt to use localhost instead of 127.0.0.1 (or vice-versa). This can
  // help when installing Backdrop in two situations:
  // - When using localhost, a socket is used. If the socket is not where PHP
  //   expects, switch to 127.0.0.1 and use TCP/IP instead.
  // - When using 127.0.0.1, if the port number is not correct, using a
  //   socket may work instead. This can happen when using local environments
  //   that use non-standard port numbers for the database.
  if ($last_exception && ($last_exception->getCode() === $this->connectionRefusedErrorCode)) {
    $localhost_invalid = $original_connection_info['default']['host'] === 'localhost';
    $local_ip_invalid = $original_connection_info['default']['host'] === '127.0.0.1';
    if ($localhost_invalid) {
      $modified_connection_info['default']['host'] = '127.0.0.1';
      $modified_connection_info['default']['port'] = '3306';
    }
    elseif ($local_ip_invalid) {
      $modified_connection_info['default']['host'] = 'localhost';
      $modified_connection_info['default']['port'] = '';
    }
    if ($original_connection_info != $modified_connection_info) {
      Database::removeConnection('default');
      Database::addConnectionInfo('default', 'default', $modified_connection_info['default']);
      try {
        Database::getConnection('default', 'default');

        // The modified database connection was successful. Provide an
        // informative help message asking the installer to adjust the
        // values.
        $extra_help = st('Connecting to "@broken_host" was not successful, but connecting to "@working_host" with the same credentials was successful. Try setting the database host (under Advanced options) to "@working_host".', array(
          '@broken_host' => $localhost_invalid ? 'localhost' : '127.0.0.1',
          '@working_host' => $localhost_invalid ? '127.0.0.1' : 'localhost',
        ));
      }
      catch (Exception $e) {
        $last_exception = $e;
      }
    }
  }

  // Attempt to create the database if it is not found.
  if ($last_exception && ($last_exception->getCode() === $this->databaseNotFoundErrorCode)) {
    $database = $modified_connection_info['default']['database'];
    unset($modified_connection_info['default']['database']);

    // Before attempting to create a database, ensure the name is acceptable.
    if (preg_match('/[^A-Za-z0-9_.]+/', $database)) {
      $this->fail(st('Database %database is not valid. Only use alphanumeric characters and underscores in the database name.', array('%database' => $database)));
      return FALSE;
    }

    // Remove the database from the connection, then attempt to create it.
    Database::removeConnection('default');
    Database::addConnectionInfo('default', 'default', $modified_connection_info['default']);
    try {
      Database::getConnection()->createDatabase($database);
      // After creating the database, we must run DatabaseTasks::connect()
      // again to be sure a connection to the new database can be established.
      Database::removeConnection('default');
      return $this->connect();
    }
    catch (PDOException $e) {
      $last_exception = $e;
    }
  }

  // Attempts at fixing the database connection have failed, report the
  // original exception error message.
  if ($last_exception) {
    $host = $original_connection_info['default']['host'];
    if ($original_connection_info['default']['port']) {
      $host .= ':' . $original_connection_info['default']['port'];
    }
    $exception_message = preg_replace('/SQLSTATE\[.*\]/', '', $original_failed_exception->getMessage());
    $error = st('Failed to connect to your database server. The server reports the following message: %error.', array('%error' => $exception_message));

    $error .= '<div class="database-extra-help">';
    if ($extra_help) {
      $error .= $extra_help;
    }
    else {
      $error .= '<div class="item-list"><ul><li>';
      $error .= st('Is the database server running on %host?', array('%host' => $host));
      $error .= '</li><li>';
      $error .= st('Is %database the correct database name?', array('%database' => $original_connection_info['default']['database']));
      $error .= '</li><li>';
      $error .= st('Are the username and password correct?');
      $error .= '</li></ul></div>';
    }
    $error .= '</div>';
    $this->fail($error);
    return FALSE;
  }

  $this->pass('Backdrop can CONNECT to the database ok.');
  return TRUE;
}