]> _ Git - cubist_util.git/commitdiff
wait #6772 @1
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Wed, 6 Mar 2024 14:48:19 +0000 (15:48 +0100)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Wed, 6 Mar 2024 14:48:19 +0000 (15:48 +0100)
src/Files/VirtualDirectory.php

index ae9a822257b834fb70d3a7e077505591f2364011..b14999106071479004df87d047e6261c04511b93 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace Cubist\Util\Files;
 
+use Cubist\Util\Text;
 use SplFileInfo;
 
 class VirtualDirectory
@@ -12,7 +13,10 @@ class VirtualDirectory
     protected $_directories;
     protected $_contents;
     protected $_tmp;
-    protected $_dirs = array();
+    protected $_dirs = [];
+    protected $_attributes = null;
+
+    protected $_logger;
 
     /** @var IVirtualDirectoryErrorListener|null */
     protected $_errorListener = null;
@@ -26,6 +30,21 @@ class VirtualDirectory
         $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
      */
@@ -97,10 +116,12 @@ class VirtualDirectory
      */
     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
@@ -108,7 +129,9 @@ class VirtualDirectory
             Files::mkdir($dir);
         }
 
+
         foreach ($this->_copy as $to => $from) {
+
             if ($delete) {
                 $existing[$to] = true;
             }
@@ -118,30 +141,40 @@ class VirtualDirectory
                 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');
     }
 
     /**
@@ -168,13 +201,9 @@ class VirtualDirectory
 
     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);
             }
         }
@@ -209,4 +238,34 @@ class VirtualDirectory
     {
         $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