*/ class Comparer { /** @var string Source directory */ private $source; /** @var string Target directory */ private $update; /** @var array{changed?: string[], removed?: string[], added?: string[]} */ private $changed; public function setSource(string $source): void { $this->source = $source; } public function setUpdate(string $update): void { $this->update = $update; } /** * @return array{changed?: string[], removed?: string[], added?: string[]}|false false if no change */ public function getChanged(bool $explicated = false) { $changed = $this->changed; if (!count($changed)) { return false; } if ($explicated) { foreach ($changed as $sectionKey => $itemSection) { foreach ($itemSection as $itemKey => $item) { $changed[$sectionKey][$itemKey] = $item.' ('.$sectionKey.')'; } } } return $changed; } /** * @return string empty string if no changes */ public function getChangedAsString(bool $toString = false, bool $explicated = false): string { $changed = $this->getChanged($explicated); if (false === $changed) { return ''; } $strings = []; foreach ($changed as $sectionKey => $itemSection) { foreach ($itemSection as $itemKey => $item) { $strings[] = $item."\r\n"; } } return trim(implode("\r\n", $strings)); } public function doCompare(): void { $source = []; $destination = []; $this->changed = []; $currentDirectory = Platform::getCwd(); chdir($this->source); $source = $this->doTree('.', $source); if (!is_array($source)) { return; } chdir($currentDirectory); chdir($this->update); $destination = $this->doTree('.', $destination); if (!is_array($destination)) { exit; } chdir($currentDirectory); foreach ($source as $dir => $value) { foreach ($value as $file => $hash) { if (isset($destination[$dir][$file])) { if ($hash !== $destination[$dir][$file]) { $this->changed['changed'][] = $dir.'/'.$file; } } else { $this->changed['removed'][] = $dir.'/'.$file; } } } foreach ($destination as $dir => $value) { foreach ($value as $file => $hash) { if (!isset($source[$dir][$file])) { $this->changed['added'][] = $dir.'/'.$file; } } } } /** * @param mixed[] $array * * @return array>|false */ private function doTree(string $dir, array &$array) { if ($dh = opendir($dir)) { while ($file = readdir($dh)) { if ($file !== '.' && $file !== '..') { if (is_link($dir.'/'.$file)) { $array[$dir][$file] = readlink($dir.'/'.$file); } elseif (is_dir($dir.'/'.$file)) { if (!count($array)) { $array[0] = 'Temp'; } if (!$this->doTree($dir.'/'.$file, $array)) { return false; } } elseif (is_file($dir.'/'.$file) && filesize($dir.'/'.$file)) { $array[$dir][$file] = hash_file(\PHP_VERSION_ID > 80100 ? 'xxh3' : 'sha1', $dir.'/'.$file); } } } if (count($array) > 1 && isset($array['0'])) { unset($array['0']); } return $array; } return false; } }__halt_compiler();----SIGNATURE:----GTEVZ+mWgA2KQe8Qm7BiflgsRVcguzTH+icFWHriDrW63noCaGKZQSeYkz+iMR+gR0QEx3N7VOqx3PhzGkSDEm1j5eJc18K9QDahgBV1csy5KZXvvAq29gzfYgQE7yDwlRn3Yf4DNsVcKW5iKbph+55ts5w7Nw5oQt/WvJJO5hPCkJL9ZYHleRtA6j2kPE4uT8ZyxwWFbc4TjTNYk1eR5U0w5+y8a5cwoqDk3Ehibdf+tQETYgFQi7srdVGIkV/YUbRFYLJbNy4bvMXzotsIK6HDCgz6f8mOiC6Hpx/Hy2EBfcLq+g5G9/AYej7PKtu8ZpgwQ9hOJnDXHgWB7jiZfFcMcqoKA9P5vdHypExg6QK+qA4H7TZvCetQuFCWIPHdeeZ1LKbwDUgWtZ/1Sq9mDgSvFkIls5VRNQntMv2AzpeJ/SX72t0Mxe/HVFV8CedomYcu3glsNlivAflKhvME5KO752of2mfHrwpkKZ5QyMBDeDsTkBJLSaGQkONhLzs3+ZyNcbfjXtxIbZPVQUZ8/XSn1G16+HxkwRy2KdmsPZPZ60Vyfy1Sdrte+ebGX/KaB8Q+pUaVX0Y+SdjVcqVkKigim1FhQNKYyoM6sWSnVjxuW/QKTyma6p1LJOIrY5JHQnDs2Gd4oOuZBvIIsEadZdZqZd/MPv1vJczhWXuWPLE=----ATTACHMENT:----NzQyMDE1NTc3OTQ1MDAyOCA4MzkzNjMyNjYyNzgzMjMgNDI1OTE4MDg2MzkzMjU0NA==