1.20.x install.inc protected DatabaseTasks::connect()

Check if we can connect to the database.

File

includes/install.inc, line 498
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;
  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)) {
    if ($original_connection_info['default']['host'] === 'localhost') {
      $modified_connection_info['default']['host'] = '127.0.0.1';
      $modified_connection_info['default']['port'] = '3306';
    }
    elseif ($original_connection_info['default']['host'] === '127.0.0.1') {
      $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();
        $last_exception = FALSE;

        // Connection was successful, but settings.php needs to be updated.
        $db_settings = $modified_connection_info['default'];
        $settings['database'] = array(
          'value' => $db_settings['driver'] . '://' . rawurlencode($db_settings['username']) . ':' . rawurlencode($db_settings['password']) . '@' . $db_settings['host'] . ($db_settings['port'] ? (':' . $db_settings['port']) : '') . '/' . rawurlencode($db_settings['database']),
          'required' => TRUE,
        );
        $settings['database_prefix'] = array(
          'value' => $db_settings['prefix']['default'],
        );
        backdrop_rewrite_settings($settings);
      }
      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);
      $last_exception = FALSE;
    }
    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="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>';
    $this->fail($error);
    return FALSE;
  }

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