PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 4.14.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v4.14.1
5.12.0 5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / core / Db / Adapter / Mysqli.php
matomo / app / core / Db / Adapter Last commit date
Pdo 3 years ago Mysqli.php 3 years ago
Mysqli.php
256 lines
1 <?php
2 /**
3 * Matomo - free/libre analytics platform
4 *
5 * @link https://matomo.org
6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
7 *
8 */
9 namespace Piwik\Db\Adapter;
10
11 use Exception;
12 use Piwik\Config;
13 use Piwik\Db;
14 use Piwik\Db\AdapterInterface;
15 use Piwik\Piwik;
16 use Zend_Config;
17 use Zend_Db_Adapter_Mysqli;
18
19 /**
20 */
21 class Mysqli extends Zend_Db_Adapter_Mysqli implements AdapterInterface
22 {
23 /**
24 * Constructor
25 *
26 * @param array|Zend_Config $config database configuration
27 */
28
29 // this is used for indicate TransactionLevel Cache
30 public $supportsUncommitted;
31
32 public function __construct($config)
33 {
34 // Enable LOAD DATA INFILE
35 $config['driver_options'][MYSQLI_OPT_LOCAL_INFILE] = true;
36
37 if ($config['enable_ssl']) {
38 if (!empty($config['ssl_key'])) {
39 $config['driver_options']['ssl_key'] = $config['ssl_key'];
40 }
41 if (!empty($config['ssl_cert'])) {
42 $config['driver_options']['ssl_cert'] = $config['ssl_cert'];
43 }
44 if (!empty($config['ssl_ca'])) {
45 $config['driver_options']['ssl_ca'] = $config['ssl_ca'];
46 }
47 if (!empty($config['ssl_ca_path'])) {
48 $config['driver_options']['ssl_ca_path'] = $config['ssl_ca_path'];
49 }
50 if (!empty($config['ssl_cipher'])) {
51 $config['driver_options']['ssl_cipher'] = $config['ssl_cipher'];
52 }
53 if (!empty($config['ssl_no_verify'])) {
54 $config['driver_options']['ssl_no_verify'] = $config['ssl_no_verify'];
55 }
56 }
57
58 parent::__construct($config);
59 }
60
61 /**
62 * Reset the configuration variables in this adapter.
63 */
64 public function resetConfig()
65 {
66 $this->_config = array();
67 }
68
69 /**
70 * Return default port.
71 *
72 * @return int
73 */
74 public static function getDefaultPort()
75 {
76 return 3306;
77 }
78
79 protected function _connect()
80 {
81 if ($this->_connection) {
82 return;
83 }
84
85 // The default error reporting of mysqli changed in PHP 8.1. To circumvent problems in our error handling we set
86 // the erroring reporting to the default that was used prior PHP 8.1
87 // See https://php.watch/versions/8.1/mysqli-error-mode for more details
88 mysqli_report(MYSQLI_REPORT_OFF);
89
90 parent::_connect();
91
92 $this->_connection->query('SET sql_mode = "' . Db::SQL_MODE . '"');
93 }
94
95 /**
96 * Check MySQL version
97 *
98 * @throws Exception
99 */
100 public function checkServerVersion()
101 {
102 $serverVersion = $this->getServerVersion();
103 $requiredVersion = Config::getInstance()->General['minimum_mysql_version'];
104
105 if (version_compare($serverVersion, $requiredVersion) === -1) {
106 throw new Exception(Piwik::translate('General_ExceptionDatabaseVersion', array('MySQL', $serverVersion, $requiredVersion)));
107 }
108 }
109
110 /**
111 * Returns the MySQL server version
112 *
113 * @return null|string
114 */
115 public function getServerVersion()
116 {
117 // prioritizing SELECT @@VERSION in case the connection version string is incorrect (which can
118 // occur on Azure)
119 $versionInfo = $this->fetchAll('SELECT @@VERSION');
120
121 if (count($versionInfo)) {
122 return $versionInfo[0]['@@VERSION'];
123 }
124
125 return parent::getServerVersion();
126 }
127
128 /**
129 * Check client version compatibility against database server
130 *
131 * @throws Exception
132 */
133 public function checkClientVersion()
134 {
135 $serverVersion = $this->getServerVersion();
136 $clientVersion = $this->getClientVersion();
137
138 // incompatible change to DECIMAL implementation in 5.0.3
139 if (version_compare($serverVersion, '5.0.3') >= 0
140 && version_compare($clientVersion, '5.0.3') < 0
141 ) {
142 throw new Exception(Piwik::translate('General_ExceptionIncompatibleClientServerVersions', array('MySQL', $clientVersion, $serverVersion)));
143 }
144 }
145
146 /**
147 * Return number of affected rows in last query
148 *
149 * @param mixed $queryResult Result from query()
150 * @return int
151 */
152 public function rowCount($queryResult)
153 {
154 return mysqli_affected_rows($this->_connection);
155 }
156
157 /**
158 * Returns true if this adapter's required extensions are enabled
159 *
160 * @return bool
161 */
162 public static function isEnabled()
163 {
164 $extensions = @get_loaded_extensions();
165 return in_array('mysqli', $extensions);
166 }
167
168 /**
169 * Returns true if this adapter supports blobs as fields
170 *
171 * @return bool
172 */
173 public function hasBlobDataType()
174 {
175 return true;
176 }
177
178 /**
179 * Returns true if this adapter supports bulk loading
180 *
181 * @return bool
182 */
183 public function hasBulkLoader()
184 {
185 return true;
186 }
187
188 /**
189 * Test error number
190 *
191 * @param Exception $e
192 * @param string $errno
193 * @return bool
194 */
195 public function isErrNo($e, $errno)
196 {
197 return self::isMysqliErrorNumber($e, $this->_connection, $errno);
198 }
199
200 /**
201 * Test error number
202 *
203 * @param Exception $e
204 * @param string $errno
205 * @return bool
206 */
207 public static function isMysqliErrorNumber($e, $connection, $errno)
208 {
209 if (is_null($connection)) {
210 if (preg_match('/(?:\[|\s)([0-9]{4})(?:\]|\s)/', $e->getMessage(), $match)) {
211 return $match[1] == $errno;
212 }
213 return mysqli_connect_errno() == $errno;
214 }
215
216 return mysqli_errno($connection) == $errno;
217 }
218
219 /**
220 * Execute unprepared SQL query and throw away the result
221 *
222 * Workaround some SQL statements not compatible with prepare().
223 * See http://framework.zend.com/issues/browse/ZF-1398
224 *
225 * @param string $sqlQuery
226 * @return int Number of rows affected (SELECT/INSERT/UPDATE/DELETE)
227 */
228 public function exec($sqlQuery)
229 {
230 $rc = mysqli_query($this->_connection, $sqlQuery);
231 $rowsAffected = mysqli_affected_rows($this->_connection);
232 if (!is_bool($rc)) {
233 mysqli_free_result($rc);
234 }
235 return $rowsAffected;
236 }
237
238
239 /**
240 * Get client version
241 *
242 * @return string
243 */
244 public function getClientVersion()
245 {
246 $this->_connect();
247
248 $version = $this->_connection->server_version;
249 $major = (int)($version / 10000);
250 $minor = (int)($version % 10000 / 100);
251 $revision = (int)($version % 100);
252
253 return $major . '.' . $minor . '.' . $revision;
254 }
255 }
256