Create an update query from old and new values of a document

@param   array   $old        Old values of document
@param   array   $new        New values of document
@param   string  $prefix
@return  void
485023
public function createUpdateQuery($old, $new, $prefix = "")
    {
        $update = [];

        foreach ($new as $key => $value) {
            if (is_array($old) && array_key_exists($key, $old)) {
                if (is_array($value) && strstr(key($value), '$') !== false) {
                    $update[key($value)][$prefix . $key] = $value[key($value)];
                } elseif (is_array($value) && is_array($old[$key])) {
                    if (!empty($old[$key])) {
                        $embeddedUpdate = array_merge_recursive($update, $this->createUpdateQuery($old[$key], $value, $prefix . $key . "."));
                        if (isset($embeddedUpdate['$unset']) && array_values($old[$key]) === $old[$key] && $value !== null && count(array_filter(array_keys($value), 'is_string')) == 0) {
                            $update['$set'][$prefix . $key] = array_values($value);
                        } else {
                            foreach ($embeddedUpdate as $updateOperator => $value) {
                                if (!isset($update[$updateOperator])) {
                                    $update[$updateOperator] = [];
                                }
                                $update[$updateOperator] += $value;
                            }
                        }
                    } elseif (!empty($value)) {
                        $update['$set'][$prefix . $key] = $value;
                    }
                } else {
                    if ($value !== null && $value !== $old[$key]) {
                        if ($value instanceof \MongoDB\BSON\UTCDateTime && $old[$key] instanceof \MongoDB\BSON\UTCDateTime) {
                            if (serialize($value) != serialize($old[$key])) {
                                $update['$set'][$prefix . $key] = $value;
                            }
                        } else {
                            $update['$set'][$prefix . $key] = $value;
                        }
                    } elseif ($value === null && $old[$key] !== null) {
                        $update['$unset'][$prefix . $key] = 1;
                    }
                }
            } else {
                if (is_array($value) && strstr(key($value), '$') === false) {
                    $embeddedQuery = $this->createUpdateQuery([], $value, $prefix . $key . ".");
                    if (count($embeddedQuery) == 1 && key($embeddedQuery) == '$set') {
                        $update['$set'][$prefix . $key] = $value;
                    } else {
                        $update = array_merge_recursive($update, $embeddedQuery);
                    }
                } elseif (is_array($value) && strstr(key($value), '$') !== false) {
                    $update[key($value)][$prefix . $key] = $value[key($value)];
                } else {
                    $update['$set'][$prefix . $key] = $value;
                }
            }

            unset($new[$key]);
            unset($old[$key]);
        }
        if (is_array($old)) {
            foreach (array_keys($old) as $key) {
                $update['$unset'][$prefix . $key] = 1;
            }
        }

        if (isset($update['$set']['_id'])) {
            unset($update['$set']['_id']);
        }

        foreach ($update as $modifier => $value) {
            if (empty($value)) {
                unset($update[$modifier]);
            }
        }

        return $update;
    }
452086
protected function mergeGroup(array $new, array $old)
    {
        $new['namespace'] = $this->formatNamespace($new, $old);

        $new['prefix'] = $this->formatPrefix($new, $old);

        foreach (['middleware', 'providers', 'scopes', 'before', 'after'] as $option) {
            $new[$option] = $this->formatArrayBasedOption($option, $new);
        }

        if (isset($new['domain'])) {
            unset($old['domain']);
        }

        if (isset($new['conditionalRequest'])) {
            unset($old['conditionalRequest']);
        }

        if (isset($new['uses'])) {
            $new['uses'] = $this->formatUses($new, $old);
        }

        $new['where'] = array_merge(Arr::get($old, 'where', []), Arr::get($new, 'where', []));

        if (isset($old['as'])) {
            $new['as'] = trim($old['as'].'.'.Arr::get($new, 'as', ''), '.');
        }

        return array_merge_recursive(array_except($old, ['namespace', 'prefix', 'where', 'as']), $new);
    }
617407
public function ApplyBan($NewBan = NULL, $OldBan = NULL) {
      if (!$NewBan && !$OldBan)
         return;

      $OldUsers = array();
      $OldUserIDs = array();

      $NewUsers = array();
      $NewUserIDs = array();
      
      $AllBans = $this->AllBans();
      
      if ($NewBan) {
         // Get a list of users affected by the new ban.
         if (isset($NewBan['BanID']))
            $AllBans[$NewBan['BanID']] = $NewBan;

         $NewUsers = $this->SQL
            ->Select('u.UserID, u.Banned')
            ->From('User u')
            ->Where($this->BanWhere($NewBan))
            ->Get()->ResultArray();
         $NewUserIDs = ConsolidateArrayValuesByKey($NewUsers, 'UserID');
      } elseif (isset($OldBan['BanID'])) {
         unset($AllBans[$OldBan['BanID']]);
      }

      if ($OldBan) {
         // Get a list of users affected by the old ban.
         $OldUsers = $this->SQL
            ->Select('u.UserID, u.LastIPAddress, u.Name, u.Email, u.Banned')
            ->From('User u')
            ->Where($this->BanWhere($OldBan))
            ->Get()->ResultArray();
         $OldUserIDs = ConsolidateArrayValuesByKey($OldUsers, 'UserID');
      }

      // Check users that need to be unbanned.
      foreach ($OldUsers as $User) {
         if (in_array($User['UserID'], $NewUserIDs))
            continue;
         // TODO check the user against the other bans.
         $this->SaveUser($User, FALSE);
      }

      // Check users that need to be banned.
      foreach ($NewUsers as $User) {
         if ($User['Banned'])
            continue;
         $this->SaveUser($User, TRUE, $NewBan);
      }
   }
266627
public function renameCheck($oldName, $newName)
    {
        if (!$this->hasCheck($oldName)) {
            throw SchemaException::tableCheckDoesNotExist($this->getName(), $oldName);
        }

        if ($this->hasCheck($newName)) {
            throw SchemaException::tableCheckAlreadyExists($this->getName(), $newName);
        }

        $this->checks[$oldName]->setName($newName);
        $this->checks[$newName] = $this->checks[$oldName];
        unset($this->checks[$oldName]);
    }
220086
public function renameTable($oldName, $newName)
    {
        if (!$this->hasTable($oldName)) {
            throw SchemaException::schemaTableDoesNotExist($this->getName(), $oldName);
        }

        if ($this->hasTable($newName)) {
            throw SchemaException::schemaTableAlreadyExists($this->getName(), $newName);
        }

        $this->tables[$oldName]->setName($newName);
        $this->tables[$newName] = $this->tables[$oldName];

        unset($this->tables[$oldName]);
    }
1216336
public function cas($key, $old_value, $new_value)
    {
        $connection = $this->getConnection($key);
        $this->writeToRemote(array(
            'cmd' => 'cas',
            'md5' => md5(serialize($old_value)),
            'key' => $key,
            'value' => $new_value,
        ), $connection);
        return $this->readFromRemote($connection);
    }
304427
protected static function formatGroupPrefix($new, $old)
    {
        $prefix = isset($old['prefix']) ? $old['prefix'] : null;

        if (isset($new['prefix'])) {
            return trim($prefix, '/') .'/' .trim($new['prefix'], '/');
        }

        return $prefix;
    }
519666
private function buildDiffTable(Text $old, Text $new) {
        $diffTable = [array_fill(0, count($new) + 1, 0)];
        for ($row = 1; $row <= count($old); $row++) {
            $diffTable[$row] = [0];
            for ($col = 1; $col <= count($new); $col++) {
                $diffTable[$row][$col] = $old[$row - 1] === $new[$col - 1]
                    ? $diffTable[$row - 1][$col - 1] + 1
                    : max($diffTable[$row - 1][$col], $diffTable[$row][$col - 1]);
            }
        }

        return $diffTable;
    }
652425
public function mergeConditionAttribute( $old, $new ) {
		try {
			$condition = $this->condition_factory->merge( $old, $new );
		} catch ( ConfigurationException $e ) {
			throw new ConfigurationException( 'Route condition is not a valid route string or condition.' );
		}

		return $condition;
	}
712283
public function edit( $oldItem, $newItem )
	{
		$index	= $this->getIndex( $oldItem );
		$this->list[$index]	= $newItem;
		return $this->write();
	}
1006521
public function rename($old, $new)
    {
        return ($this->isConnected() === true) ? ftp_rename($this->getConnection(), $old, $new) : false;
    }
310189
protected static function mergeGroup($new, $old)
    {
        $new['prefix'] = self::formatGroupPrefix($new, $old);

        $new['class'] = self::formatGroupClass($new, $old);

        return array_merge(Arr::except($old, array('prefix', 'class')), $new);
    }
1084646
protected static function formatUsesPrefix($new, $old)
    {
        if (isset($new['namespace'])) {
            return isset($old['namespace']) && \strpos($new['namespace'], '\\') !== 0
                ? \trim($old['namespace'], '\\').'\\'.\trim($new['namespace'], '\\')
                : \trim($new['namespace'], '\\');
        }

        return $old['namespace'] ?? null;
    }
656633
public function replaceFile($old, $new, array $content)
    {
        $oldFileContent = file_get_contents($old);
        file_put_contents($new, vsprintf($oldFileContent, $content));
        unlink($old);
    }
679097
public function renameTable($old, $new)
    {
        $this->replaceText("`$old`", "`$new`");
        $this->replaceText("\"$old\"", "\"$new\"");
        $this->replaceText(Convert::symbol2sql($old), Convert::symbol2sql($new));
    }
1217052
public static function mergeGroup($new, $old)
	{
		$new['namespace'] = static::formatUsesPrefix($new, $old);

		$new['prefix'] = static::formatGroupPrefix($new, $old);

		if (isset($new['domain'])) unset($old['domain']);

		return array_merge_recursive(array_except($old, array('namespace', 'prefix')), $new);
	}
768501
protected function apply(array $new, $purge = false)
    {
        $old = $this->collection;

        // Delete old values
        // Note: make sure not to overwrite / detach original object to make changes be globally effective
        if ($purge) {
            foreach ($old as $key => $value) {
                unset($old[$key]);
            }
        }

        // Set new values
        foreach ($new as $key => $value) {
            $old[$key] = $value;
        }
    }