|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
declare(strict_types=1); |
|
4
|
|
|
|
|
5
|
|
|
namespace voku\db; |
|
6
|
|
|
|
|
7
|
|
|
use voku\cache\Cache; |
|
8
|
|
|
use voku\helper\Phonetic; |
|
9
|
|
|
|
|
10
|
|
|
/** |
|
11
|
|
|
* Helper: This class can handle extra functions that use the "Simple-MySQLi"-classes. |
|
12
|
|
|
*/ |
|
13
|
|
|
class Helper |
|
14
|
|
|
{ |
|
15
|
|
|
/** |
|
16
|
|
|
* @param DB $dbConnection |
|
17
|
|
|
* |
|
18
|
|
|
* @return string |
|
19
|
|
|
*/ |
|
20
|
8 |
|
private static function generateCacheKey(DB $dbConnection): string |
|
21
|
|
|
{ |
|
22
|
|
|
// init |
|
23
|
8 |
|
$configTmp = []; |
|
24
|
|
|
|
|
25
|
8 |
|
$configOrig = $dbConnection->getConfig(); |
|
26
|
8 |
|
\array_walk_recursive( |
|
27
|
8 |
|
$configOrig, |
|
28
|
|
|
static function ($k, $v) use (&$configTmp) { |
|
29
|
8 |
|
$configTmp[] = $v; |
|
30
|
8 |
|
$configTmp[] = $k; |
|
31
|
8 |
|
} |
|
32
|
|
|
); |
|
33
|
|
|
|
|
34
|
8 |
|
return \implode('--', $configTmp); |
|
35
|
|
|
} |
|
36
|
|
|
|
|
37
|
|
|
/** |
|
38
|
|
|
* Optimize tables |
|
39
|
|
|
* |
|
40
|
|
|
* @param array $tables database table names |
|
41
|
|
|
* @param DB|null $dbConnection <p>Use <strong>null</strong> to get your first singleton instance.</p> |
|
42
|
|
|
* |
|
43
|
|
|
* @return int |
|
44
|
|
|
*/ |
|
45
|
1 |
View Code Duplication |
public static function optimizeTables(array $tables = [], DB $dbConnection = null): int |
|
|
|
|
|
|
46
|
|
|
{ |
|
47
|
1 |
|
if ($dbConnection === null) { |
|
48
|
1 |
|
$dbConnection = DB::getInstance(); |
|
49
|
|
|
} |
|
50
|
|
|
|
|
51
|
1 |
|
$optimized = 0; |
|
52
|
1 |
|
if (!empty($tables)) { |
|
53
|
1 |
|
foreach ($tables as $table) { |
|
54
|
1 |
|
$optimize = 'OPTIMIZE TABLE ' . $dbConnection->quote_string($table); |
|
55
|
1 |
|
$result = $dbConnection->query($optimize); |
|
56
|
1 |
|
if ($result) { |
|
57
|
1 |
|
$optimized++; |
|
58
|
|
|
} |
|
59
|
|
|
} |
|
60
|
|
|
} |
|
61
|
|
|
|
|
62
|
1 |
|
return $optimized; |
|
63
|
|
|
} |
|
64
|
|
|
|
|
65
|
|
|
/** |
|
66
|
|
|
* Repair tables |
|
67
|
|
|
* |
|
68
|
|
|
* @param array $tables database table names |
|
69
|
|
|
* @param DB|null $dbConnection <p>Use <strong>null</strong> to get your first singleton instance.</p> |
|
70
|
|
|
* |
|
71
|
|
|
* @return int |
|
72
|
|
|
*/ |
|
73
|
1 |
View Code Duplication |
public static function repairTables(array $tables = [], DB $dbConnection = null): int |
|
|
|
|
|
|
74
|
|
|
{ |
|
75
|
1 |
|
if ($dbConnection === null) { |
|
76
|
1 |
|
$dbConnection = DB::getInstance(); |
|
77
|
|
|
} |
|
78
|
|
|
|
|
79
|
1 |
|
$optimized = 0; |
|
80
|
1 |
|
if (!empty($tables)) { |
|
81
|
1 |
|
foreach ($tables as $table) { |
|
82
|
1 |
|
$optimize = 'REPAIR TABLE ' . $dbConnection->quote_string($table); |
|
83
|
1 |
|
$result = $dbConnection->query($optimize); |
|
84
|
1 |
|
if ($result) { |
|
85
|
1 |
|
$optimized++; |
|
86
|
|
|
} |
|
87
|
|
|
} |
|
88
|
|
|
} |
|
89
|
|
|
|
|
90
|
1 |
|
return $optimized; |
|
91
|
|
|
} |
|
92
|
|
|
|
|
93
|
|
|
/** |
|
94
|
|
|
* Check if "mysqlnd"-driver is used. |
|
95
|
|
|
* |
|
96
|
|
|
* @return bool |
|
97
|
|
|
*/ |
|
98
|
91 |
|
public static function isMysqlndIsUsed(): bool |
|
99
|
|
|
{ |
|
100
|
91 |
|
static $_mysqlnd_is_used = null; |
|
101
|
|
|
|
|
102
|
91 |
|
if ($_mysqlnd_is_used === null) { |
|
103
|
|
|
$_mysqlnd_is_used = ( |
|
104
|
1 |
|
\extension_loaded('mysqlnd') |
|
105
|
|
|
&& |
|
106
|
1 |
|
\function_exists('mysqli_fetch_all') |
|
107
|
|
|
); |
|
108
|
|
|
} |
|
109
|
|
|
|
|
110
|
91 |
|
return $_mysqlnd_is_used; |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
/** |
|
114
|
|
|
* Check if the current environment supports "utf8mb4". |
|
115
|
|
|
* |
|
116
|
|
|
* @param DB $dbConnection |
|
117
|
|
|
* |
|
118
|
|
|
* @return bool |
|
119
|
|
|
*/ |
|
120
|
8 |
|
public static function isUtf8mb4Supported(DB $dbConnection = null): bool |
|
121
|
|
|
{ |
|
122
|
|
|
/** |
|
123
|
|
|
* https://make.wordpress.org/core/2015/04/02/the-utf8mb4-upgrade/ |
|
124
|
|
|
* |
|
125
|
|
|
* - You’re currently using the utf8 character set. |
|
126
|
|
|
* - Your MySQL server is version 5.5.3 or higher (including all 10.x versions of MariaDB). |
|
127
|
|
|
* - Your MySQL client libraries are version 5.5.3 or higher. If you’re using mysqlnd, 5.0.9 or higher. |
|
128
|
|
|
* |
|
129
|
|
|
* INFO: utf8mb4 is 100% backwards compatible with utf8. |
|
130
|
|
|
*/ |
|
131
|
8 |
|
if ($dbConnection === null) { |
|
132
|
|
|
$dbConnection = DB::getInstance(); |
|
133
|
|
|
} |
|
134
|
|
|
|
|
135
|
8 |
|
$server_version = self::get_mysql_server_version($dbConnection); |
|
136
|
8 |
|
$client_version = self::get_mysql_client_version($dbConnection); |
|
137
|
|
|
|
|
138
|
|
|
if ( |
|
139
|
8 |
|
$server_version >= 50503 |
|
140
|
|
|
&& |
|
141
|
|
|
( |
|
142
|
|
|
( |
|
143
|
8 |
|
self::isMysqlndIsUsed() |
|
144
|
|
|
&& |
|
145
|
8 |
|
$client_version >= 50009 |
|
146
|
|
|
) |
|
147
|
|
|
|| |
|
148
|
|
|
( |
|
149
|
|
|
!self::isMysqlndIsUsed() |
|
150
|
|
|
&& |
|
151
|
8 |
|
$client_version >= 50503 |
|
152
|
|
|
) |
|
153
|
|
|
) |
|
154
|
|
|
|
|
155
|
|
|
) { |
|
156
|
8 |
|
return true; |
|
157
|
|
|
} |
|
158
|
|
|
|
|
159
|
|
|
return false; |
|
160
|
|
|
} |
|
161
|
|
|
|
|
162
|
|
|
/** |
|
163
|
|
|
* A phonetic search algorithms for different languages. |
|
164
|
|
|
* |
|
165
|
|
|
* INFO: if you need better performance, please save the "voku\helper\Phonetic"-output into the DB and search for it |
|
166
|
|
|
* |
|
167
|
|
|
* @param string $searchString |
|
168
|
|
|
* @param string $searchFieldName |
|
169
|
|
|
* @param string $idFieldName |
|
170
|
|
|
* @param string $language <p>en, de, fr</p> |
|
171
|
|
|
* @param string $table |
|
172
|
|
|
* @param array $whereArray |
|
173
|
|
|
* @param DB|null $dbConnection <p>use <strong>null</strong> if you will use the current database-connection</p> |
|
174
|
|
|
* @param string|null $databaseName <p>use <strong>null</strong> if you will use the current database</p> |
|
175
|
|
|
* @param bool $useCache use cache? |
|
176
|
|
|
* @param int $cacheTTL cache-ttl in seconds |
|
177
|
|
|
* |
|
178
|
|
|
* @return array |
|
179
|
|
|
*/ |
|
180
|
2 |
|
public static function phoneticSearch( |
|
181
|
|
|
string $searchString, |
|
182
|
|
|
string $searchFieldName, |
|
183
|
|
|
string $idFieldName = null, |
|
184
|
|
|
string $language = 'de', |
|
185
|
|
|
string $table = '', |
|
186
|
|
|
array $whereArray = null, |
|
187
|
|
|
DB $dbConnection = null, |
|
188
|
|
|
string $databaseName = null, |
|
189
|
|
|
bool $useCache = false, |
|
190
|
|
|
int $cacheTTL = 3600 |
|
191
|
|
|
): array { |
|
192
|
|
|
// init |
|
193
|
2 |
|
$cacheKey = null; |
|
194
|
|
|
|
|
195
|
2 |
|
if ($dbConnection === null) { |
|
196
|
2 |
|
$dbConnection = DB::getInstance(); |
|
197
|
|
|
} |
|
198
|
|
|
|
|
199
|
2 |
View Code Duplication |
if ($table === '') { |
|
200
|
|
|
$debug = new Debug($dbConnection); |
|
201
|
|
|
$debug->displayError('Invalid table name, table name in empty.', false); |
|
202
|
|
|
|
|
203
|
|
|
return []; |
|
204
|
|
|
} |
|
205
|
|
|
|
|
206
|
2 |
|
if ($idFieldName === null) { |
|
207
|
|
|
$idFieldName = 'id'; |
|
208
|
|
|
} |
|
209
|
|
|
|
|
210
|
2 |
|
if ($whereArray === null) { |
|
211
|
|
|
$whereArray = []; |
|
212
|
|
|
} |
|
213
|
|
|
|
|
214
|
2 |
|
$whereSQL = $dbConnection->_parseArrayPair($whereArray, 'AND'); |
|
215
|
2 |
|
if ($whereSQL) { |
|
216
|
2 |
|
$whereSQL = 'AND ' . $whereSQL; |
|
217
|
|
|
} |
|
218
|
|
|
|
|
219
|
2 |
|
if ($databaseName) { |
|
|
|
|
|
|
220
|
|
|
$databaseName = $dbConnection->quote_string(\trim($databaseName)) . '.'; |
|
221
|
|
|
} |
|
222
|
|
|
|
|
223
|
|
|
// get the row |
|
224
|
2 |
|
$query = 'SELECT ' . $dbConnection->quote_string($searchFieldName) . ', ' . $dbConnection->quote_string($idFieldName) . ' |
|
225
|
2 |
|
FROM ' . $databaseName . $dbConnection->quote_string($table) . ' |
|
226
|
|
|
WHERE 1 = 1 |
|
227
|
2 |
|
' . $whereSQL . ' |
|
228
|
|
|
'; |
|
229
|
|
|
|
|
230
|
2 |
View Code Duplication |
if ($useCache) { |
|
231
|
1 |
|
$cache = new Cache(null, null, false, $useCache); |
|
232
|
1 |
|
$cacheKey = 'sql-phonetic-search-' . \md5($query); |
|
233
|
|
|
|
|
234
|
|
|
if ( |
|
235
|
1 |
|
$cache->getCacheIsReady() |
|
236
|
|
|
&& |
|
237
|
1 |
|
$cache->existsItem($cacheKey) |
|
238
|
|
|
) { |
|
239
|
1 |
|
return $cache->getItem($cacheKey); |
|
240
|
|
|
} |
|
241
|
|
|
} else { |
|
242
|
1 |
|
$cache = false; |
|
243
|
|
|
} |
|
244
|
|
|
|
|
245
|
2 |
|
$result = $dbConnection->query($query); |
|
246
|
|
|
|
|
247
|
2 |
|
if (!$result instanceof Result) { |
|
248
|
|
|
return []; |
|
249
|
|
|
} |
|
250
|
|
|
|
|
251
|
|
|
// make sure the row exists |
|
252
|
2 |
|
if ($result->num_rows <= 0) { |
|
253
|
|
|
return []; |
|
254
|
|
|
} |
|
255
|
|
|
|
|
256
|
2 |
|
$dataToSearchIn = []; |
|
257
|
|
|
/** @noinspection LoopWhichDoesNotLoopInspection */ |
|
258
|
|
|
/** @noinspection PhpAssignmentInConditionInspection */ |
|
259
|
2 |
|
while ($tmpArray = $result->fetchArray()) { |
|
260
|
2 |
|
$dataToSearchIn[$tmpArray[$idFieldName]] = $tmpArray[$searchFieldName]; |
|
261
|
|
|
} |
|
262
|
|
|
|
|
263
|
2 |
|
$phonetic = new Phonetic($language); |
|
264
|
2 |
|
$return = $phonetic->phonetic_matches($searchString, $dataToSearchIn); |
|
265
|
|
|
|
|
266
|
|
|
// save into the cache |
|
267
|
|
View Code Duplication |
if ( |
|
268
|
2 |
|
$cacheKey !== null |
|
269
|
|
|
&& |
|
270
|
2 |
|
$useCache |
|
271
|
|
|
&& |
|
272
|
2 |
|
$cache instanceof Cache |
|
273
|
|
|
&& |
|
274
|
2 |
|
$cache->getCacheIsReady() |
|
275
|
|
|
) { |
|
276
|
1 |
|
$cache->setItem($cacheKey, $return, $cacheTTL); |
|
277
|
|
|
} |
|
278
|
|
|
|
|
279
|
2 |
|
return $return; |
|
280
|
|
|
} |
|
281
|
|
|
|
|
282
|
|
|
/** |
|
283
|
|
|
* A string that represents the MySQL client library version. |
|
284
|
|
|
* |
|
285
|
|
|
* @param DB $dbConnection |
|
286
|
|
|
* |
|
287
|
|
|
* @return string |
|
288
|
|
|
*/ |
|
289
|
8 |
View Code Duplication |
public static function get_mysql_client_version(DB $dbConnection = null): string |
|
|
|
|
|
|
290
|
|
|
{ |
|
291
|
8 |
|
static $MYSQL_CLIENT_VERSION_CACHE = []; |
|
292
|
|
|
|
|
293
|
8 |
|
if ($dbConnection === null) { |
|
294
|
|
|
$dbConnection = DB::getInstance(); |
|
295
|
|
|
} |
|
296
|
|
|
|
|
297
|
8 |
|
$cacheKey = self::generateCacheKey($dbConnection); |
|
298
|
|
|
|
|
299
|
8 |
|
if (isset($MYSQL_CLIENT_VERSION_CACHE[$cacheKey])) { |
|
300
|
8 |
|
return $MYSQL_CLIENT_VERSION_CACHE[$cacheKey]; |
|
301
|
|
|
} |
|
302
|
|
|
|
|
303
|
2 |
|
$doctrineConnection = $dbConnection->getDoctrineConnection(); |
|
304
|
2 |
|
if ($doctrineConnection) { |
|
305
|
|
|
$doctrineWrappedConnection = $doctrineConnection->getWrappedConnection(); |
|
306
|
|
|
if ($doctrineWrappedConnection instanceof \Doctrine\DBAL\Driver\PDOConnection) { |
|
307
|
|
|
return $MYSQL_CLIENT_VERSION_CACHE[$cacheKey] = $doctrineWrappedConnection->getAttribute(5); // 5 = PDO::ATTR_CLIENT_VERSION |
|
308
|
|
|
} |
|
309
|
|
|
} |
|
310
|
|
|
|
|
311
|
2 |
|
$mysqli_link = $dbConnection->getLink(); |
|
312
|
2 |
|
if (!$mysqli_link) { |
|
313
|
|
|
return ''; |
|
314
|
|
|
} |
|
315
|
|
|
|
|
316
|
2 |
|
return $MYSQL_CLIENT_VERSION_CACHE[$cacheKey] = (string) \mysqli_get_client_version($mysqli_link); |
|
317
|
|
|
} |
|
318
|
|
|
|
|
319
|
|
|
/** |
|
320
|
|
|
* Returns a string representing the version of the MySQL server that the MySQLi extension is connected to. |
|
321
|
|
|
* |
|
322
|
|
|
* @param DB $dbConnection |
|
323
|
|
|
* |
|
324
|
|
|
* @return string |
|
325
|
|
|
*/ |
|
326
|
8 |
View Code Duplication |
public static function get_mysql_server_version(DB $dbConnection = null): string |
|
|
|
|
|
|
327
|
|
|
{ |
|
328
|
8 |
|
static $MYSQL_SERVER_VERSION_CACHE = []; |
|
329
|
|
|
|
|
330
|
8 |
|
if ($dbConnection === null) { |
|
331
|
|
|
$dbConnection = DB::getInstance(); |
|
332
|
|
|
} |
|
333
|
|
|
|
|
334
|
8 |
|
$cacheKey = self::generateCacheKey($dbConnection); |
|
335
|
|
|
|
|
336
|
8 |
|
if (isset($MYSQL_SERVER_VERSION_CACHE[$cacheKey])) { |
|
337
|
8 |
|
return $MYSQL_SERVER_VERSION_CACHE[$cacheKey]; |
|
338
|
|
|
} |
|
339
|
|
|
|
|
340
|
2 |
|
$doctrineConnection = $dbConnection->getDoctrineConnection(); |
|
341
|
2 |
|
if ($doctrineConnection) { |
|
342
|
|
|
$doctrineWrappedConnection = $doctrineConnection->getWrappedConnection(); |
|
343
|
|
|
if ($doctrineWrappedConnection instanceof \Doctrine\DBAL\Driver\PDOConnection) { |
|
344
|
|
|
return $MYSQL_SERVER_VERSION_CACHE[$cacheKey] = (string) $doctrineWrappedConnection->getServerVersion(); |
|
345
|
|
|
} |
|
346
|
|
|
} |
|
347
|
|
|
|
|
348
|
2 |
|
$mysqli_link = $dbConnection->getLink(); |
|
349
|
2 |
|
if (!$mysqli_link) { |
|
350
|
|
|
return ''; |
|
351
|
|
|
} |
|
352
|
|
|
|
|
353
|
2 |
|
return $MYSQL_SERVER_VERSION_CACHE[$cacheKey] = (string) \mysqli_get_server_version($mysqli_link); |
|
354
|
|
|
} |
|
355
|
|
|
|
|
356
|
|
|
/** |
|
357
|
|
|
* Return all db-fields from a table. |
|
358
|
|
|
* |
|
359
|
|
|
* @param string $table |
|
360
|
|
|
* @param bool $useStaticCache |
|
361
|
|
|
* @param DB|null $dbConnection <p>use <strong>null</strong> if you will use the current database-connection</p> |
|
362
|
|
|
* @param string|null $databaseName <p>use <strong>null</strong> if you will use the current database</p> |
|
363
|
|
|
* |
|
364
|
|
|
* @return array |
|
365
|
|
|
*/ |
|
366
|
1 |
|
public static function getDbFields(string $table, bool $useStaticCache = true, DB $dbConnection = null, string $databaseName = null): array |
|
367
|
|
|
{ |
|
368
|
1 |
|
static $DB_FIELDS_CACHE = []; |
|
369
|
|
|
|
|
370
|
|
|
// use the static cache |
|
371
|
|
|
if ( |
|
372
|
1 |
|
$useStaticCache |
|
373
|
|
|
&& |
|
374
|
1 |
|
isset($DB_FIELDS_CACHE[$table]) |
|
375
|
|
|
) { |
|
376
|
1 |
|
return $DB_FIELDS_CACHE[$table]; |
|
377
|
|
|
} |
|
378
|
|
|
|
|
379
|
|
|
// init |
|
380
|
1 |
|
$dbFields = []; |
|
381
|
|
|
|
|
382
|
1 |
|
if ($dbConnection === null) { |
|
383
|
1 |
|
$dbConnection = DB::getInstance(); |
|
384
|
|
|
} |
|
385
|
|
|
|
|
386
|
1 |
View Code Duplication |
if ($table === '') { |
|
387
|
|
|
$debug = new Debug($dbConnection); |
|
388
|
|
|
$debug->displayError('Invalid table name, table name in empty.', false); |
|
389
|
|
|
|
|
390
|
|
|
return []; |
|
391
|
|
|
} |
|
392
|
|
|
|
|
393
|
1 |
|
if ($databaseName) { |
|
|
|
|
|
|
394
|
|
|
$databaseName = $dbConnection->quote_string(\trim($databaseName)) . '.'; |
|
395
|
|
|
} |
|
396
|
|
|
|
|
397
|
1 |
|
$sql = 'SHOW COLUMNS FROM ' . $databaseName . $dbConnection->escape($table); |
|
398
|
1 |
|
$result = $dbConnection->query($sql); |
|
399
|
|
|
|
|
400
|
1 |
|
if ($result instanceof Result && $result->num_rows > 0) { |
|
401
|
1 |
|
foreach ($result->fetchAllArray() as $tmpResult) { |
|
402
|
1 |
|
$dbFields[] = $tmpResult['Field']; |
|
403
|
|
|
} |
|
404
|
|
|
} |
|
405
|
|
|
|
|
406
|
|
|
// add to static cache |
|
407
|
1 |
|
$DB_FIELDS_CACHE[$table] = $dbFields; |
|
408
|
|
|
|
|
409
|
1 |
|
return $dbFields; |
|
410
|
|
|
} |
|
411
|
|
|
|
|
412
|
|
|
/** |
|
413
|
|
|
* Copy row within a DB table and making updates to the columns. |
|
414
|
|
|
* |
|
415
|
|
|
* @param string $table |
|
416
|
|
|
* @param array $whereArray |
|
417
|
|
|
* @param array $updateArray |
|
418
|
|
|
* @param array $ignoreArray |
|
419
|
|
|
* @param DB|null $dbConnection <p>Use <strong>null</strong> to get your first singleton instance.</p> |
|
420
|
|
|
* @param string|null $databaseName <p>use <strong>null</strong> if you will use the current database</p> |
|
421
|
|
|
* |
|
422
|
|
|
* @return false|int|string "int|string" (insert_id) by "<b>INSERT / REPLACE</b>"-queries<br /> |
|
423
|
|
|
* "false" on error |
|
424
|
|
|
*/ |
|
425
|
1 |
|
public static function copyTableRow( |
|
426
|
|
|
string $table, |
|
427
|
|
|
array $whereArray, |
|
428
|
|
|
array $updateArray = [], |
|
429
|
|
|
array $ignoreArray = [], |
|
430
|
|
|
DB $dbConnection = null, |
|
431
|
|
|
string $databaseName = null |
|
432
|
|
|
) { |
|
433
|
|
|
// init |
|
434
|
1 |
|
$table = \trim($table); |
|
435
|
|
|
|
|
436
|
1 |
|
if ($dbConnection === null) { |
|
437
|
1 |
|
$dbConnection = DB::getInstance(); |
|
438
|
|
|
} |
|
439
|
|
|
|
|
440
|
1 |
View Code Duplication |
if ($table === '') { |
|
441
|
|
|
$debug = new Debug($dbConnection); |
|
442
|
|
|
$debug->displayError('Invalid table name, table name in empty.', false); |
|
443
|
|
|
|
|
444
|
|
|
return false; |
|
445
|
|
|
} |
|
446
|
|
|
|
|
447
|
1 |
|
$whereSQL = $dbConnection->_parseArrayPair($whereArray, 'AND'); |
|
448
|
1 |
|
if ($whereSQL) { |
|
449
|
1 |
|
$whereSQL = 'AND ' . $whereSQL; |
|
450
|
|
|
} |
|
451
|
|
|
|
|
452
|
1 |
|
if ($databaseName) { |
|
|
|
|
|
|
453
|
|
|
$databaseName = $dbConnection->quote_string(\trim($databaseName)) . '.'; |
|
454
|
|
|
} |
|
455
|
|
|
|
|
456
|
|
|
// get the row |
|
457
|
1 |
|
$query = 'SELECT * FROM ' . $databaseName . $dbConnection->quote_string($table) . ' |
|
458
|
|
|
WHERE 1 = 1 |
|
459
|
1 |
|
' . $whereSQL . ' |
|
460
|
|
|
'; |
|
461
|
1 |
|
$result = $dbConnection->query($query); |
|
462
|
|
|
|
|
463
|
|
|
// make sure the row exists |
|
464
|
1 |
|
if ($result instanceof Result && $result->num_rows > 0) { |
|
465
|
|
|
|
|
466
|
|
|
/** @noinspection LoopWhichDoesNotLoopInspection */ |
|
467
|
|
|
/** @noinspection PhpAssignmentInConditionInspection */ |
|
468
|
1 |
|
while ($tmpArray = $result->fetchArray()) { |
|
469
|
|
|
|
|
470
|
|
|
// re-build a new DB query and ignore some field-names |
|
471
|
1 |
|
$bindings = []; |
|
472
|
1 |
|
$insert_keys = ''; |
|
473
|
1 |
|
$insert_values = ''; |
|
474
|
|
|
|
|
475
|
1 |
|
foreach ($tmpArray as $fieldName => $value) { |
|
476
|
1 |
|
if (!\in_array($fieldName, $ignoreArray, true)) { |
|
477
|
1 |
|
if (\array_key_exists($fieldName, $updateArray)) { |
|
478
|
1 |
|
$insert_keys .= ',' . $fieldName; |
|
479
|
1 |
|
$insert_values .= ',?'; |
|
480
|
1 |
|
$bindings[] = $updateArray[$fieldName]; // INFO: do not escape non selected data |
|
481
|
|
|
} else { |
|
482
|
1 |
|
$insert_keys .= ',' . $fieldName; |
|
483
|
1 |
|
$insert_values .= ',?'; |
|
484
|
1 |
|
$bindings[] = $value; // INFO: do not escape non selected data |
|
485
|
|
|
} |
|
486
|
|
|
} |
|
487
|
|
|
} |
|
488
|
|
|
|
|
489
|
1 |
|
$insert_keys = \ltrim($insert_keys, ','); |
|
490
|
1 |
|
$insert_values = \ltrim($insert_values, ','); |
|
491
|
|
|
|
|
492
|
|
|
// insert the "copied" row |
|
493
|
1 |
|
$new_query = 'INSERT INTO ' . $databaseName . $dbConnection->quote_string($table) . ' |
|
494
|
1 |
|
(' . $insert_keys . ') |
|
495
|
|
|
VALUES |
|
496
|
1 |
|
(' . $insert_values . ') |
|
497
|
|
|
'; |
|
498
|
|
|
|
|
499
|
1 |
|
$return = $dbConnection->query($new_query, $bindings); |
|
500
|
1 |
|
\assert(\is_int($return) || \is_string($return) || $return === false); |
|
501
|
|
|
|
|
502
|
1 |
|
return $return; |
|
503
|
|
|
} |
|
504
|
|
|
} |
|
505
|
|
|
|
|
506
|
|
|
return false; |
|
507
|
|
|
} |
|
508
|
|
|
} |
|
509
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.