namespace Cubist\Util\Files;
+use Cubist\Util\Text;
use SplFileInfo;
class VirtualDirectory
protected $_directories;
protected $_contents;
protected $_tmp;
- protected $_dirs = array();
+ protected $_dirs = [];
+ protected $_attributes = null;
+
+ protected $_logger;
/** @var IVirtualDirectoryErrorListener|null */
protected $_errorListener = null;
$this->_tmp = array();
}
+ /**
+ * @param mixed $logger
+ */
+ public function setLogger($logger): void
+ {
+ $this->_logger = $logger;
+ }
+
+ protected function log($message)
+ {
+ if ($this->_logger !== null) {
+ $this->_logger->log('Vdir : ' . $message);
+ }
+ }
+
/**
* @return IVirtualDirectoryErrorListener|null
*/
*/
public function sync($delete = false)
{
+ $this->log('Begin sync : delete ' . $delete);
$existing = array();
foreach ($this->_directories as $to => $from) {
$this->_addDirectory($from, $to);
+ $this->log('Add directory : ' . $to);
}
// Create dirs before copying
Files::mkdir($dir);
}
+
foreach ($this->_copy as $to => $from) {
+
if ($delete) {
$existing[$to] = true;
}
continue;
}
- if (!file_exists($to) || filesize($from) !== filesize($to) || filemtime($from) !== filemtime($to)) {
+ if (!$this->compare($from, $to)) {
$to_esc = escapeshellarg($to);
$from_esc = escapeshellarg($from);
`cp -p $from_esc $to_esc`;
+ $this->log('Copy file ' . $to);
if (!file_exists($to)) {
$this->throwError(sprintf('Failed to copy %s to %s', $from, $to));
- continue;
}
+
}
+ $this->log('Test and copy file ' . $to);
}
foreach ($this->_contents as $to => $data) {
+
if ($delete) {
$existing[$to] = true;
}
file_put_contents($to, $data);
+ $this->log('Copy contents into ' . $to);
}
+
if ($delete) {
$this->_delete($existing);
+ $this->log('Delete files');
}
+
$this->cleanTemp();
+ $this->log('Clean temp');
+
+ $this->log('Synced ok');
}
/**
protected function _delete($existing = array())
{
- $files = Files::getRecursiveDirectoryIterator($this->_path);
- foreach ($files as $file) {
- if ($file->isDir()) {
- continue;
- }
- $path = $file->getRealPath();
- if (!isset($existing[$path]) && file_exists($path)) {
+ $files = $this->_getFilesAttributes();
+ foreach ($files as $path => $attrs) {
+ if (!isset($existing[$path])) {
@unlink($path);
}
}
{
$this->_tmp[] = $temp;
}
+
+ public function compare($from, $to)
+ {
+ $this->_getFilesAttributes();
+ if (!isset($this->_attributes[$to])) {
+ return false;
+ }
+ $a = $this->_attributes[$to];
+ if (filesize($from) != $a['size']) {
+ return false;
+ }
+ if (filemtime($from) != $a['mtime']) {
+ return false;
+ }
+ return true;
+ }
+
+ protected function _getFilesAttributes()
+ {
+ if (null !== $this->_attributes) {
+ return $this->_attributes;
+ }
+ $e = Text::explodeNewLines(`cd $this->_path;find . -type f -print0 | xargs -0 ls -l --time-style="+%s"`);
+ foreach ($e as $line) {
+ $f = preg_split('/\s+/', $line);
+ $a = ['size' => (int)$f[4], 'mtime' => (int)$f[5]];
+ $this->_attributes[$this->_path . substr($f[6], 2)] = $a;
+ }
+ $this->log('Got files attributes');
+ }
}
\ No newline at end of file