Seditio Source
Root |
./othercms/phpBB3/includes/functions_database_helper.php
<?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');
    }
}