|
|
@@ -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()
|
|
|
}
|
|
|
|
|
|
/**
|