Kaynağa Gözat

use a glob iterator to stream through as many matches as needed

El RIDO 3 yıl önce
ebeveyn
işleme
b8593b1bf2
1 değiştirilmiş dosya ile 34 ekleme ve 114 silme
  1. 34 114
      lib/Data/Filesystem.php

+ 34 - 114
lib/Data/Filesystem.php

@@ -340,63 +340,25 @@ class Filesystem extends AbstractData
      */
     protected function _getExpiredPastes($batchsize)
     {
-        $pastes     = array();
-        $firstLevel = array_filter(
-            scandir($this->_path),
-            'PrivateBin\Data\Filesystem::_isFirstLevelDir'
-        );
-        if (count($firstLevel) > 0) {
-            // try at most 10 times the $batchsize pastes before giving up
-            for ($i = 0, $max = $batchsize * 10; $i < $max; ++$i) {
-                $firstKey    = array_rand($firstLevel);
-                $secondLevel = array_filter(
-                    scandir($this->_path . DIRECTORY_SEPARATOR . $firstLevel[$firstKey]),
-                    'PrivateBin\Data\Filesystem::_isSecondLevelDir'
-                );
-
-                // skip this folder in the next checks if it is empty
-                if (count($secondLevel) == 0) {
-                    unset($firstLevel[$firstKey]);
-                    continue;
-                }
-
-                $secondKey = array_rand($secondLevel);
-                $path      = $this->_path . DIRECTORY_SEPARATOR .
-                    $firstLevel[$firstKey] . DIRECTORY_SEPARATOR .
-                    $secondLevel[$secondKey];
-                if (!is_dir($path)) {
-                    continue;
-                }
-                $thirdLevel = array_filter(
-                    array_map(
-                        function ($filename) {
-                            return strlen($filename) >= 20 ?
-                                substr($filename, 0, -4) :
-                                $filename;
-                        },
-                        scandir($path)
-                    ),
-                    'PrivateBin\\Model\\Paste::isValidId'
-                );
-                if (count($thirdLevel) == 0) {
-                    continue;
-                }
-                $thirdKey = array_rand($thirdLevel);
-                $pasteid  = $thirdLevel[$thirdKey];
-                if (in_array($pasteid, $pastes)) {
-                    continue;
-                }
-
-                if ($this->exists($pasteid)) {
-                    $data = $this->read($pasteid);
-                    if (
-                        array_key_exists('expire_date', $data['meta']) &&
-                        $data['meta']['expire_date'] < time()
-                    ) {
-                        $pastes[] = $pasteid;
-                        if (count($pastes) >= $batchsize) {
-                            break;
-                        }
+        $pastes = array();
+        $files  = $this->_getPasteIterator();
+        $count  = 0;
+        $time   = time();
+        foreach ($files as $file) {
+            if ($file->isDir()) {
+                continue;
+            }
+            $pasteid = $file->getBasename('.php');
+            if ($this->exists($pasteid)) {
+                $data = $this->read($pasteid);
+                if (
+                    array_key_exists('expire_date', $data['meta']) &&
+                    $data['meta']['expire_date'] < $time
+                ) {
+                    $pastes[] = $pasteid;
+                    ++$count;
+                    if ($count >= $batchsize) {
+                        break;
                     }
                 }
             }
@@ -409,45 +371,11 @@ class Filesystem extends AbstractData
      */
     public function getAllPastes()
     {
-        $pastes     = array();
-        $firstLevel = array_filter(
-            scandir($this->_path),
-            'PrivateBin\Data\Filesystem::_isFirstLevelDir'
-        );
-        if (count($firstLevel) > 0) {
-            foreach ($firstLevel as $firstKey) {
-                $secondLevel = array_filter(
-                    scandir($this->_path . DIRECTORY_SEPARATOR . $firstKey),
-                    'PrivateBin\Data\Filesystem::_isSecondLevelDir'
-                );
-
-                // skip this folder
-                if (count($secondLevel) == 0) {
-                    continue;
-                }
-
-                foreach ($secondLevel as $secondKey) {
-                    $path = $this->_path . DIRECTORY_SEPARATOR . $firstKey .
-                        DIRECTORY_SEPARATOR . $secondKey;
-                    if (!is_dir($path)) {
-                        continue;
-                    }
-                    $thirdLevel = array_filter(
-                        array_map(
-                            function ($filename) {
-                                return strlen($filename) >= 20 ?
-                                    substr($filename, 0, -4) :
-                                    $filename;
-                            },
-                            scandir($path)
-                        ),
-                        'PrivateBin\\Model\\Paste::isValidId'
-                    );
-                    if (count($thirdLevel) == 0) {
-                        continue;
-                    }
-                    $pastes += $thirdLevel;
-                }
+        $pastes = array();
+        $files  = $this->_getPasteIterator();
+        foreach ($files as $file) {
+            if ($file->isFile()) {
+                $pastes[] = $file->getBasename('.php');
             }
         }
         return $pastes;
@@ -490,28 +418,20 @@ class Filesystem extends AbstractData
     }
 
     /**
-     * Check that the given element is a valid first level directory.
-     *
-     * @access private
-     * @param  string $element
-     * @return bool
-     */
-    private function _isFirstLevelDir($element)
-    {
-        return $this->_isSecondLevelDir($element) &&
-            is_dir($this->_path . DIRECTORY_SEPARATOR . $element);
-    }
-
-    /**
-     * Check that the given element is a valid second level directory.
+     * Get an iterator matching paste files.
      *
      * @access private
-     * @param  string $element
-     * @return bool
+     * @return \GlobIterator
      */
-    private function _isSecondLevelDir($element)
+    private function _getPasteIterator()
     {
-        return (bool) preg_match('/^[a-f0-9]{2}$/', $element);
+        return new \GlobIterator($this->_path . DIRECTORY_SEPARATOR .
+            '[a-f0-9][a-f0-9]' . DIRECTORY_SEPARATOR .
+            '[a-f0-9][a-f0-9]' . DIRECTORY_SEPARATOR .
+            '[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]' .
+            '[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]*');
+        // need to return both files with and without .php suffix, so they can
+        // be hardened by _prependRename(), which is hooked into exists()
     }
 
     /**