Skip to content

Commit

Permalink
Merge pull request #43794 from nextcloud/fix/files/scanner-metadata-diff
Browse files Browse the repository at this point in the history
fix(files): handle multidimensional arrays in scanner
  • Loading branch information
come-nc authored May 13, 2024
2 parents 7d05983 + 3c3e45f commit e68544d
Showing 1 changed file with 47 additions and 2 deletions.
49 changes: 47 additions & 2 deletions lib/private/Files/Cache/Scanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,9 @@ public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData =
}

// Only update metadata that has changed
$newData = array_diff_assoc($data, $cacheData->getData());

// i.e. get all the values in $data that are not present in the cache already
$newData = $this->array_diff_assoc_multi($data, $cacheData->getData());

// make it known to the caller that etag has been changed and needs propagation
if (isset($newData['etag'])) {
$data['etag_changed'] = true;
Expand Down Expand Up @@ -369,6 +370,50 @@ public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $loc
return $data;
}

/**
* Compares $array1 against $array2 and returns all the values in $array1 that are not in $array2
* Note this is a one-way check - i.e. we don't care about things that are in $array2 that aren't in $array1
*
* Supports multi-dimensional arrays
* Also checks keys/indexes
* Comparisons are strict just like array_diff_assoc
* Order of keys/values does not matter
*
* @param array $array1
* @param array $array2
* @return array with the differences between $array1 and $array1
* @throws \InvalidArgumentException if $array1 isn't an actual array
*
*/
protected function array_diff_assoc_multi(array $array1, array $array2) {

$result = [];

foreach ($array1 as $key => $value) {

// if $array2 doesn't have the same key, that's a result
if (!array_key_exists($key, $array2)) {
$result[$key] = $value;
continue;
}

// if $array2's value for the same key is different, that's a result
if ($array2[$key] !== $value && !is_array($value)) {
$result[$key] = $value;
continue;
}

if (is_array($value)) {
$nestedDiff = $this->array_diff_assoc_multi($value, $array2[$key]);
if (!empty($nestedDiff)) {
$result[$key] = $nestedDiff;
continue;
}
}
}
return $result;
}

/**
* Get the children currently in the cache
*
Expand Down

0 comments on commit e68544d

Please sign in to comment.