/**
* sync local directory with ftp directory
*
* @param string $src
* @param string $dst
* @param callable|null $syncop
*
* @throws GlSyncFtpException
*/
public function syncDirectory($src, $dst, callable $syncop = null)
{
$this->login();
$files = [];
$dirs = [];
$this->getFiles($dst, "", $files, $dirs);
// delete on ftp server, files not present in local directory
foreach ($files as $name => $raw) {
if (!file_exists($src . $name)) {
$filepathFtp = $dst . strtr($name, ["\\" => "/"]);
if ($syncop) {
$syncop(self::DELETE_FILE, $filepathFtp);
}
$this->sftp->delete($filepathFtp);
}
}
// delete on ftp server, unknowns directories
$dirs = array_reverse($dirs);
foreach ($dirs as $name => $raw) {
if (!file_exists($src . $name)) {
$filepathFtp = $dst . strtr($name, ["\\" => "/"]);
if ($syncop) {
$syncop(self::DELETE_DIR, $filepathFtp);
}
$this->sftp->rmdir($filepathFtp);
}
}
// create new directories
$finderdir = new Finder();
$finderdir->directories()->ignoreDotFiles(false)->followLinks()->in($src)->notName('.git*');
/**
* @var SplFileInfo $dir
*/
foreach ($finderdir as $dir) {
$dirpathFtp = $dst . "/" . strtr($dir->getRelativePathname(), ["\\" => "/"]);
$stat = $this->sftp->stat($dirpathFtp);
if (!$stat) {
if ($syncop) {
$syncop(self::CREATE_DIR, $dirpathFtp);
}
$this->sftp->mkdir($dirpathFtp, $dir->getRealPath(), SFTP::SOURCE_LOCAL_FILE);
$this->sftp->chmod(0755, $dirpathFtp, $dir->getRealPath());
}
}
// copy new files or update if younger
$finderdir = new Finder();
$finderdir->files()->ignoreDotFiles(false)->followLinks()->in($src)->notName('.git*');
/**
* @var SplFileInfo $file
*/
foreach ($finderdir as $file) {
$filepathFtp = $dst . "/" . strtr($file->getRelativePathname(), ["\\" => "/"]);
$stat = $this->sftp->stat($filepathFtp);
if (!$stat) {
if ($syncop) {
$syncop(self::NEW_FILE, $filepathFtp);
}
$this->sftp->put($filepathFtp, $file->getRealPath(), SFTP::SOURCE_LOCAL_FILE);
} else {
$size = $this->sftp->size($filepathFtp);
if ($file->getMTime() > $stat['mtime'] || $file->getSize() != $size) {
if ($syncop) {
$syncop(self::UPDATE_FILE, $filepathFtp);
}
$this->sftp->put($filepathFtp, $file->getRealPath(), SFTP::SOURCE_LOCAL_FILE);
}
}
}
}