use a glob iterator to stream through as many matches as needed
This commit is contained in:
parent
b3699cae8f
commit
b8593b1bf2
|
@ -341,66 +341,28 @@ 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]);
|
||||
$files = $this->_getPasteIterator();
|
||||
$count = 0;
|
||||
$time = time();
|
||||
foreach ($files as $file) {
|
||||
if ($file->isDir()) {
|
||||
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;
|
||||
}
|
||||
|
||||
$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()
|
||||
$data['meta']['expire_date'] < $time
|
||||
) {
|
||||
$pastes[] = $pasteid;
|
||||
if (count($pastes) >= $batchsize) {
|
||||
++$count;
|
||||
if ($count >= $batchsize) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $pastes;
|
||||
}
|
||||
|
||||
|
@ -410,44 +372,10 @@ 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;
|
||||
}
|
||||
$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.
|
||||
* Get an iterator matching paste files.
|
||||
*
|
||||
* @access private
|
||||
* @param string $element
|
||||
* @return bool
|
||||
* @return \GlobIterator
|
||||
*/
|
||||
private function _isFirstLevelDir($element)
|
||||
private function _getPasteIterator()
|
||||
{
|
||||
return $this->_isSecondLevelDir($element) &&
|
||||
is_dir($this->_path . DIRECTORY_SEPARATOR . $element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the given element is a valid second level directory.
|
||||
*
|
||||
* @access private
|
||||
* @param string $element
|
||||
* @return bool
|
||||
*/
|
||||
private function _isSecondLevelDir($element)
|
||||
{
|
||||
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()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue