Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0 / 0 |
|
100.00% |
0 / 0 |
CRAP | |
99.08% |
108 / 109 |
|
phpbb_update_rows_avoiding_duplicates | |
0.00% |
0 / 1 |
0 | |
97.87% |
46 / 47 |
|||
phpbb_update_rows_avoiding_duplicates_notify_status | |
100.00% |
1 / 1 |
0 | |
100.00% |
62 / 62 |
<?php | |
/** | |
* | |
* This file is part of the phpBB Forum Software package. | |
* | |
* @copyright (c) phpBB Limited <https://www.phpbb.com> | |
* @license GNU General Public License, version 2 (GPL-2.0) | |
* | |
* For full copyright and license information, please see | |
* the docs/CREDITS.txt file. | |
* | |
*/ | |
/** | |
* @ignore | |
*/ | |
if (!defined('IN_PHPBB')) | |
{ | |
exit; | |
} | |
/** | |
* Updates rows in given table from a set of values to a new value. | |
* If this results in rows violating uniqueness constraints, the duplicate | |
* rows are eliminated. | |
* | |
* The only supported table is bookmarks. | |
* | |
* @param \phpbb\db\driver\driver_interface $db Database object | |
* @param string $table Table on which to perform the update | |
* @param string $column Column whose values to change | |
* @param array $from_values An array of values that should be changed | |
* @param int $to_value The new value | |
* @return null | |
*/ | |
function phpbb_update_rows_avoiding_duplicates(\phpbb\db\driver\driver_interface $db, $table, $column, $from_values, $to_value) | |
{ | |
$sql = "SELECT $column, user_id | |
FROM $table | |
WHERE " . $db->sql_in_set($column, $from_values); | |
$result = $db->sql_query($sql); | |
$old_user_ids = array(); | |
while ($row = $db->sql_fetchrow($result)) | |
{ | |
$old_user_ids[$row[$column]][] = (int) $row['user_id']; | |
} | |
$db->sql_freeresult($result); | |
$sql = "SELECT $column, user_id | |
FROM $table | |
WHERE $column = " . (int) $to_value; | |
$result = $db->sql_query($sql); | |
$new_user_ids = array(); | |
while ($row = $db->sql_fetchrow($result)) | |
{ | |
$new_user_ids[$row[$column]][] = (int) $row['user_id']; | |
} | |
$db->sql_freeresult($result); | |
$queries = array(); | |
foreach ($from_values as $from_value) | |
{ | |
if (!isset($old_user_ids[$from_value])) | |
{ | |
continue; | |
} | |
if (empty($new_user_ids)) | |
{ | |
$sql = "UPDATE $table | |
SET $column = " . (int) $to_value . " | |
WHERE $column = '" . $db->sql_escape($from_value) . "'"; | |
$queries[] = $sql; | |
} | |
else | |
{ | |
$different_user_ids = array_diff($old_user_ids[$from_value], $new_user_ids[$to_value]); | |
if (!empty($different_user_ids)) | |
{ | |
$sql = "UPDATE $table | |
SET $column = " . (int) $to_value . " | |
WHERE $column = '" . $db->sql_escape($from_value) . "' | |
AND " . $db->sql_in_set('user_id', $different_user_ids); | |
$queries[] = $sql; | |
} | |
} | |
} | |
if (!empty($queries)) | |
{ | |
$db->sql_transaction('begin'); | |
foreach ($queries as $sql) | |
{ | |
$db->sql_query($sql); | |
} | |
$sql = "DELETE FROM $table | |
WHERE " . $db->sql_in_set($column, $from_values); | |
$db->sql_query($sql); | |
$db->sql_transaction('commit'); | |
} | |
} | |
/** | |
* Updates rows in given table from a set of values to a new value. | |
* If this results in rows violating uniqueness constraints, the duplicate | |
* rows are merged respecting notify_status (0 takes precedence over 1). | |
* | |
* The only supported table is topics_watch. | |
* | |
* @param \phpbb\db\driver\driver_interface $db Database object | |
* @param string $table Table on which to perform the update | |
* @param string $column Column whose values to change | |
* @param array $from_values An array of values that should be changed | |
* @param int $to_value The new value | |
* @return null | |
*/ | |
function phpbb_update_rows_avoiding_duplicates_notify_status(\phpbb\db\driver\driver_interface $db, $table, $column, $from_values, $to_value) | |
{ | |
$sql = "SELECT $column, user_id, notify_status | |
FROM $table | |
WHERE " . $db->sql_in_set($column, $from_values); | |
$result = $db->sql_query($sql); | |
$old_user_ids = array(); | |
while ($row = $db->sql_fetchrow($result)) | |
{ | |
$old_user_ids[(int) $row['notify_status']][$row[$column]][] = (int) $row['user_id']; | |
} | |
$db->sql_freeresult($result); | |
$sql = "SELECT $column, user_id | |
FROM $table | |
WHERE $column = " . (int) $to_value; | |
$result = $db->sql_query($sql); | |
$new_user_ids = array(); | |
while ($row = $db->sql_fetchrow($result)) | |
{ | |
$new_user_ids[$row[$column]][] = (int) $row['user_id']; | |
} | |
$db->sql_freeresult($result); | |
$queries = array(); | |
$extra_updates = array( | |
0 => 'notify_status = 0', | |
1 => '', | |
); | |
foreach ($from_values as $from_value) | |
{ | |
foreach ($extra_updates as $notify_status => $extra_update) | |
{ | |
if (!isset($old_user_ids[$notify_status][$from_value])) | |
{ | |
continue; | |
} | |
if (empty($new_user_ids)) | |
{ | |
$sql = "UPDATE $table | |
SET $column = " . (int) $to_value . " | |
WHERE $column = '" . $db->sql_escape($from_value) . "'"; | |
$queries[] = $sql; | |
} | |
else | |
{ | |
$different_user_ids = array_diff($old_user_ids[$notify_status][$from_value], $new_user_ids[$to_value]); | |
if (!empty($different_user_ids)) | |
{ | |
$sql = "UPDATE $table | |
SET $column = " . (int) $to_value . " | |
WHERE $column = '" . $db->sql_escape($from_value) . "' | |
AND " . $db->sql_in_set('user_id', $different_user_ids); | |
$queries[] = $sql; | |
} | |
if ($extra_update) | |
{ | |
$same_user_ids = array_diff($old_user_ids[$notify_status][$from_value], $different_user_ids); | |
if (!empty($same_user_ids)) | |
{ | |
$sql = "UPDATE $table | |
SET $extra_update | |
WHERE $column = '" . (int) $to_value . "' | |
AND " . $db->sql_in_set('user_id', $same_user_ids); | |
$queries[] = $sql; | |
} | |
} | |
} | |
} | |
} | |
if (!empty($queries)) | |
{ | |
$db->sql_transaction('begin'); | |
foreach ($queries as $sql) | |
{ | |
$db->sql_query($sql); | |
} | |
$sql = "DELETE FROM $table | |
WHERE " . $db->sql_in_set($column, $from_values); | |
$db->sql_query($sql); | |
$db->sql_transaction('commit'); | |
} | |
} |