<?php // phpcs:ignore Standard.Category.SniffName.ErrorCode namespace WPDataAccess\Connection; /** * This class extends WodPress class wpdb to enable remote connections and connections to local databases. */ class WPDADB_WPDB extends \wpdb { /** * Indicator: ON = use SSL * * @var string */ private $ssl; /** * SSL key * * @var string */ private $ssl_key; /** * SSL certificate * * @var string */ private $ssl_cert; /** * SSL CA * * @var string */ private $ssl_ca; /** * SSL path * * @var string */ private $ssl_path; /** * SSL cipher * * @var string */ private $ssl_cipher; /** * Overwrite WPDADB_WPDB constructor * * Save schema_name * * @param string $dbuser Username (original wpdb parameter). * @param string $dbpassword Password (original wpdb parameter). * @param string $dbname Database schema name (original wpdb parameter). * @param string $dbhost Host name (original wpdb parameter). * @param string $ssl SSL on|off. * @param string $ssl_key SSL key. * @param string $ssl_cert SSL certificate. * @param string $ssl_ca SSL CA. * @param string $ssl_path SSL path. * @param string $ssl_cipher SSL cipher. */ public function __construct( $dbuser, $dbpassword, $dbname, $dbhost, // Original WordPress wpdb parameters $ssl = 'OFF', $ssl_key = null, $ssl_cert = null, $ssl_ca = null, $ssl_path = null, $ssl_cipher = null ) { $this->ssl = $ssl; $this->ssl_key = $ssl_key; $this->ssl_cert = $ssl_cert; $this->ssl_ca = $ssl_ca; $this->ssl_path = $ssl_path; $this->ssl_cipher = $ssl_cipher; if ( '' === trim( (string) $this->ssl_path ) ) { $this->ssl_path = null; } if ( '' === trim( (string) $this->ssl_cipher ) ) { $this->ssl_cipher = null; } parent::__construct( $dbuser, $dbpassword, $dbname, $dbhost ); } /** * Is connection established? * * @return bool */ public function is_connected() { return 0 === $this->dbh->connect_errno; } /** * Overwrite method * * This just adds a call to private method @ssl() * * @param bool $allow_bail Allow bail. * * @return bool */ public function db_connect( $allow_bail = false ) { $this->is_mysql = true; $client_flags = ( defined( 'MYSQL_CLIENT_FLAGS' ) ? MYSQL_CLIENT_FLAGS : 0 ); /* * Set the MySQLi error reporting off because WordPress handles its own. * This is due to the default value change from `MYSQLI_REPORT_OFF` * to `MYSQLI_REPORT_ERROR|MYSQLI_REPORT_STRICT` in PHP 8.1. */ mysqli_report( MYSQLI_REPORT_OFF ); $this->dbh = mysqli_init(); $host = $this->dbhost; $port = null; $socket = null; $is_ipv6 = false; $host_data = $this->parse_db_host( $this->dbhost ); if ( $host_data ) { list( $host, $port, $socket, $is_ipv6 ) = $host_data; // phpcs:ignore - 8.1 proof } /* * If using the `mysqlnd` library, the IPv6 address needs to be enclosed * in square brackets, whereas it doesn't while using the `libmysqlclient` library. * @see https://bugs.php.net/bug.php?id=67563 */ if ( $is_ipv6 && extension_loaded( 'mysqlnd' ) ) { $host = "[{$host}]"; } if ( 'on' === $this->ssl ) { mysqli_ssl_set( // phpcs:ignore $this->dbh, $this->ssl_key, $this->ssl_cert, $this->ssl_ca, $this->ssl_path, $this->ssl_cipher ); } mysqli_report( MYSQLI_REPORT_STRICT ); // phpcs:ignore try { if ( WP_DEBUG ) { if ( !mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags ) ) { // phpcs:ignore mysqli_report( MYSQLI_REPORT_OFF ); // phpcs:ignore return false; } } else { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged if ( !@mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags ) ) { // phpcs:ignore mysqli_report( MYSQLI_REPORT_OFF ); // phpcs:ignore return false; } } } catch ( \mysqli_sql_exception $e ) { mysqli_report( MYSQLI_REPORT_OFF ); // phpcs:ignore return false; } mysqli_report( MYSQLI_REPORT_OFF ); // phpcs:ignore if ( $this->dbh->connect_errno ) { $this->dbh = null; /* * It's possible ext/mysqli is misconfigured. Fall back to ext/mysql if: * - We haven't previously connected, and * - WP_USE_EXT_MYSQL isn't set to false, and * - ext/mysql is loaded. */ $attempt_fallback = true; if ( $this->has_connected ) { $attempt_fallback = false; } elseif ( defined( 'WP_USE_EXT_MYSQL' ) && !WP_USE_EXT_MYSQL ) { $attempt_fallback = false; } elseif ( !function_exists( 'mysql_connect' ) ) { $attempt_fallback = false; } if ( $attempt_fallback ) { $this->use_mysqli = false; return $this->db_connect( $allow_bail ); } } if ( !$this->dbh && $allow_bail ) { wp_load_translations_early(); // Load custom DB error template, if present. if ( file_exists( WP_CONTENT_DIR . '/db-error.php' ) ) { require_once WP_CONTENT_DIR . '/db-error.php'; die; } $message = '<h1>' . __( 'Error establishing a database connection' ) . "</h1>\n"; $message .= '<p>' . sprintf( /* translators: 1: wp-config.php, 2: Database host. */ __( 'This either means that the username and password information in your %1$s file is incorrect or we can&#8217;t contact the database server at %2$s. This could mean your host&#8217;s database server is down.' ), '<code>wp-config.php</code>', '<code>' . htmlspecialchars( $this->dbhost, ENT_QUOTES ) . '</code>' ) . "</p>\n"; $message .= "<ul>\n"; $message .= '<li>' . __( 'Are you sure you have the correct username and password?' ) . "</li>\n"; $message .= '<li>' . __( 'Are you sure you have typed the correct hostname?' ) . "</li>\n"; $message .= '<li>' . __( 'Are you sure the database server is running?' ) . "</li>\n"; $message .= "</ul>\n"; $message .= '<p>' . sprintf( /* translators: %s: Support forums URL. */ __( 'If you&#8217;re unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href="%s">WordPress Support Forums</a>.' ), __( 'https://wordpress.org/support/forums/' ) ) . "</p>\n"; $this->bail( $message, 'db_connect_fail' ); return false; } elseif ( $this->dbh ) { if ( !$this->has_connected ) { $this->init_charset(); } $this->has_connected = true; $this->set_charset( $this->dbh ); $this->ready = true; $this->set_sql_mode(); $this->select( $this->dbname, $this->dbh ); return true; } return false; } /** * Get connection error no * * @return mixed */ public function get_connect_errno() { return $this->dbh->connect_errno; } /** * Get connection error message * * @return mixed */ public function get_connect_error() { return $this->dbh->connect_error; } public function wpda_open_cursor( $query ) { if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) { $this->timer_start(); } if ( !empty( $this->dbh ) && $this->use_mysqli ) { $this->result = mysqli_query( $this->dbh, $query ); } $this->num_queries++; if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) { $this->log_query( $query, $this->timer_stop(), $this->get_caller(), $this->time_start, array() ); } } public function wpda_fetch_from_cursor() { if ( $this->use_mysqli && 'mysqli_result' === get_class( $this->result ) ) { return mysqli_fetch_object( $this->result ); } return null; } }