seperateFilesFromFolders($dir, $scan); } private function getFilesizesOfFiles($prefix, array $files) { $result = array(); foreach($files as $index=>$file) { $result[$index] = filesize($prefix . DIRECTORY_SEPARATOR . $file); } return $result; } function diffDirectories($dir1, $dir2, $prefix = "") { $diff = []; $scan1files = []; $scan1folders = []; if(file_exists($dir1) && is_dir($dir1)) { list($scan1files, $scan1folders) = $this->getFilesAndFolders($dir1); } $scan2files = []; $scan2folders = []; if(file_exists($dir2) && is_dir($dir2)) { list($scan2files, $scan2folders) = $this->getFilesAndFolders($dir2); } $fileCreations = array_diff($scan2files, $scan1files); $fileCreationsFilesizes = $this->getFilesizesOfFiles($dir2, $fileCreations); $fileDeletions = array_diff($scan1files, $scan2files); $fileDeletionsFilesizes = $this->getFilesizesOfFiles($dir1, $fileDeletions); $filePossibleEdits = array_intersect($scan1files, $scan2files); $allSubfolders = array_unique(array_merge($scan1folders, $scan2folders)); /*$diff[] = [ "type" => "DEBUG", "prefix" => $prefix, "fileCreations" => $fileCreations, "fileCreationsFilesizes" => $fileCreationsFilesizes, "fileDeletions" => $fileDeletions, "fileDeletionsFilesizes" => $fileDeletionsFilesizes, //"folderCreations" => $folderCreations, //"folderDeletions" => $folderDeletions, "allSubfolders" => $allSubfolders, ];*/ // search for creations and deletions, that are actually renames foreach($fileCreations as $creationIndex=>$creation) { $creationPath = $dir2 . DIRECTORY_SEPARATOR . $creation; $creationSize = $fileCreationsFilesizes[$creationIndex]; $renameContenders = array_keys($fileDeletionsFilesizes, $creationSize); if(sizeof($renameContenders) != 0) { /*$diff[] = [ "type" => "DEBUG", "comparing" => [ "creation" => $creationIndex, "deletions" => $renameContenders, ], ];*/ $creationSHA = sha1_file($creationPath); foreach($renameContenders as $contender) { $deletion = $fileDeletions[$contender]; $deletionPath = $dir1 . DIRECTORY_SEPARATOR . $deletion; $deletionSHA = sha1_file($deletionPath); if($deletionSHA == $creationSHA) { $diff[] = [ "type" => "RENAME", "before" => [ "exists" => True, "path" => $prefix . DIRECTORY_SEPARATOR . $deletion, "size" => $creationSize, ], "afterwards" => [ "exists" => True, "path" => $prefix . DIRECTORY_SEPARATOR . $creation, "size" => $creationSize, ] ]; unset($fileCreations[$creationIndex]); unset($fileDeletions[$contender]); break; } } } } foreach($fileCreations as $index=>$creation) { $diff[] = [ "type" => "CREATION", "before" => [ "exists" => False, ], "afterwards" => [ "exists" => True, "path" => $prefix . DIRECTORY_SEPARATOR . $creation, "size" => $fileCreationsFilesizes[$index], ] ]; } foreach($fileDeletions as $index=>$deletion) { $diff[] = [ "type" => "DELETION", "before" => [ "exists" => True, "path" => $prefix . DIRECTORY_SEPARATOR . $deletion, "size" => $fileDeletionsFilesizes[$index], ], "afterwards" => [ "exists" => False, ], ]; } foreach($filePossibleEdits as $possibleEdit) { $file1 = $dir1 . DIRECTORY_SEPARATOR . $possibleEdit; $file2 = $dir2 . DIRECTORY_SEPARATOR . $possibleEdit; $file1Size = filesize($file1); $file2Size = filesize($file2); if(filemtime($file1) == filemtime($file2)) { //not different because same mtime continue; } else { // mtime different, but could just have gotten touched without modifications if($file1Size == $file2Size) { // if filesize is the same check for binary differences $handle1 = fopen($file1, 'rb'); $handle2 = fopen($file2, 'rb'); $filesdifferent = false; while(!feof($handle1)) { if(fread($handle1, 8192) != fread($handle2, 8192)) { // files are different $filesdifferent = true; break; } } fclose($handle1); fclose($handle2); if(!$filesdifferent) { continue; } } } $diff[] = [ "type" => "EDIT", "before" => [ "path" => $prefix . DIRECTORY_SEPARATOR . $possibleEdit, "size" => $file1Size, ], "afterwards" => [ "path" => $prefix . DIRECTORY_SEPARATOR . $possibleEdit, "size" => $file2Size, ] ]; } foreach($allSubfolders as $folder) { array_push($diff, ...($this->diffDirectories($dir1 . DIRECTORY_SEPARATOR . $folder, $dir2 . DIRECTORY_SEPARATOR . $folder, $prefix . DIRECTORY_SEPARATOR . $folder))); } return $diff; } }