|
@@ -12,9 +12,8 @@
|
|
|
|
|
|
|
|
namespace PrivateBin\Data;
|
|
namespace PrivateBin\Data;
|
|
|
|
|
|
|
|
-use Exception;
|
|
|
|
|
-use PrivateBin\Json;
|
|
|
|
|
use PrivateBin\Model\Paste;
|
|
use PrivateBin\Model\Paste;
|
|
|
|
|
+use PrivateBin\Persistence\DataStore;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Filesystem
|
|
* Filesystem
|
|
@@ -23,15 +22,6 @@ use PrivateBin\Model\Paste;
|
|
|
*/
|
|
*/
|
|
|
class Filesystem extends AbstractData
|
|
class Filesystem extends AbstractData
|
|
|
{
|
|
{
|
|
|
- /**
|
|
|
|
|
- * directory where data is stored
|
|
|
|
|
- *
|
|
|
|
|
- * @access private
|
|
|
|
|
- * @static
|
|
|
|
|
- * @var string
|
|
|
|
|
- */
|
|
|
|
|
- private static $_dir = 'data/';
|
|
|
|
|
-
|
|
|
|
|
/**
|
|
/**
|
|
|
* get instance of singleton
|
|
* get instance of singleton
|
|
|
*
|
|
*
|
|
@@ -51,8 +41,7 @@ class Filesystem extends AbstractData
|
|
|
is_array($options) &&
|
|
is_array($options) &&
|
|
|
array_key_exists('dir', $options)
|
|
array_key_exists('dir', $options)
|
|
|
) {
|
|
) {
|
|
|
- self::$_dir = $options['dir'] . DIRECTORY_SEPARATOR;
|
|
|
|
|
- self::_init();
|
|
|
|
|
|
|
+ DataStore::setPath($options['dir']);
|
|
|
}
|
|
}
|
|
|
return self::$_instance;
|
|
return self::$_instance;
|
|
|
}
|
|
}
|
|
@@ -63,19 +52,19 @@ class Filesystem extends AbstractData
|
|
|
* @access public
|
|
* @access public
|
|
|
* @param string $pasteid
|
|
* @param string $pasteid
|
|
|
* @param array $paste
|
|
* @param array $paste
|
|
|
- * @throws Exception
|
|
|
|
|
* @return bool
|
|
* @return bool
|
|
|
*/
|
|
*/
|
|
|
public function create($pasteid, $paste)
|
|
public function create($pasteid, $paste)
|
|
|
{
|
|
{
|
|
|
$storagedir = self::_dataid2path($pasteid);
|
|
$storagedir = self::_dataid2path($pasteid);
|
|
|
- if (is_file($storagedir . $pasteid)) {
|
|
|
|
|
|
|
+ $file = $storagedir . $pasteid;
|
|
|
|
|
+ if (is_file($file)) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
if (!is_dir($storagedir)) {
|
|
if (!is_dir($storagedir)) {
|
|
|
mkdir($storagedir, 0700, true);
|
|
mkdir($storagedir, 0700, true);
|
|
|
}
|
|
}
|
|
|
- return (bool) file_put_contents($storagedir . $pasteid, Json::encode($paste));
|
|
|
|
|
|
|
+ return DataStore::store($file, $paste);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -156,20 +145,19 @@ class Filesystem extends AbstractData
|
|
|
* @param string $parentid
|
|
* @param string $parentid
|
|
|
* @param string $commentid
|
|
* @param string $commentid
|
|
|
* @param array $comment
|
|
* @param array $comment
|
|
|
- * @throws Exception
|
|
|
|
|
* @return bool
|
|
* @return bool
|
|
|
*/
|
|
*/
|
|
|
public function createComment($pasteid, $parentid, $commentid, $comment)
|
|
public function createComment($pasteid, $parentid, $commentid, $comment)
|
|
|
{
|
|
{
|
|
|
$storagedir = self::_dataid2discussionpath($pasteid);
|
|
$storagedir = self::_dataid2discussionpath($pasteid);
|
|
|
- $filename = $pasteid . '.' . $commentid . '.' . $parentid;
|
|
|
|
|
- if (is_file($storagedir . $filename)) {
|
|
|
|
|
|
|
+ $file = $storagedir . $pasteid . '.' . $commentid . '.' . $parentid;
|
|
|
|
|
+ if (is_file($file)) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
if (!is_dir($storagedir)) {
|
|
if (!is_dir($storagedir)) {
|
|
|
mkdir($storagedir, 0700, true);
|
|
mkdir($storagedir, 0700, true);
|
|
|
}
|
|
}
|
|
|
- return (bool) file_put_contents($storagedir . $filename, Json::encode($comment));
|
|
|
|
|
|
|
+ return DataStore::store($file, $comment);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -238,8 +226,9 @@ class Filesystem extends AbstractData
|
|
|
protected function _getExpiredPastes($batchsize)
|
|
protected function _getExpiredPastes($batchsize)
|
|
|
{
|
|
{
|
|
|
$pastes = array();
|
|
$pastes = array();
|
|
|
|
|
+ $mainpath = DataStore::getPath();
|
|
|
$firstLevel = array_filter(
|
|
$firstLevel = array_filter(
|
|
|
- scandir(self::$_dir),
|
|
|
|
|
|
|
+ scandir($mainpath),
|
|
|
'self::_isFirstLevelDir'
|
|
'self::_isFirstLevelDir'
|
|
|
);
|
|
);
|
|
|
if (count($firstLevel) > 0) {
|
|
if (count($firstLevel) > 0) {
|
|
@@ -247,7 +236,7 @@ class Filesystem extends AbstractData
|
|
|
for ($i = 0, $max = $batchsize * 10; $i < $max; ++$i) {
|
|
for ($i = 0, $max = $batchsize * 10; $i < $max; ++$i) {
|
|
|
$firstKey = array_rand($firstLevel);
|
|
$firstKey = array_rand($firstLevel);
|
|
|
$secondLevel = array_filter(
|
|
$secondLevel = array_filter(
|
|
|
- scandir(self::$_dir . $firstLevel[$firstKey]),
|
|
|
|
|
|
|
+ scandir($mainpath . DIRECTORY_SEPARATOR . $firstLevel[$firstKey]),
|
|
|
'self::_isSecondLevelDir'
|
|
'self::_isSecondLevelDir'
|
|
|
);
|
|
);
|
|
|
|
|
|
|
@@ -258,8 +247,9 @@ class Filesystem extends AbstractData
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
$secondKey = array_rand($secondLevel);
|
|
$secondKey = array_rand($secondLevel);
|
|
|
- $path = self::$_dir . $firstLevel[$firstKey] .
|
|
|
|
|
- DIRECTORY_SEPARATOR . $secondLevel[$secondKey];
|
|
|
|
|
|
|
+ $path = $mainpath . DIRECTORY_SEPARATOR .
|
|
|
|
|
+ $firstLevel[$firstKey] . DIRECTORY_SEPARATOR .
|
|
|
|
|
+ $secondLevel[$secondKey];
|
|
|
if (!is_dir($path)) {
|
|
if (!is_dir($path)) {
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
@@ -293,34 +283,6 @@ class Filesystem extends AbstractData
|
|
|
return $pastes;
|
|
return $pastes;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * Initialize data store
|
|
|
|
|
- *
|
|
|
|
|
- * @access private
|
|
|
|
|
- * @static
|
|
|
|
|
- * @return void
|
|
|
|
|
- */
|
|
|
|
|
- private static function _init()
|
|
|
|
|
- {
|
|
|
|
|
- // Create storage directory if it does not exist.
|
|
|
|
|
- if (!is_dir(self::$_dir)) {
|
|
|
|
|
- if (!@mkdir(self::$_dir, 0700)) {
|
|
|
|
|
- throw new Exception('unable to create directory ' . self::$_dir, 10);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- $file = self::$_dir . DIRECTORY_SEPARATOR . '.htaccess';
|
|
|
|
|
- if (!is_file($file)) {
|
|
|
|
|
- $writtenBytes = @file_put_contents(
|
|
|
|
|
- $file,
|
|
|
|
|
- 'Require all denied' . PHP_EOL,
|
|
|
|
|
- LOCK_EX
|
|
|
|
|
- );
|
|
|
|
|
- if ($writtenBytes === false || $writtenBytes < 19) {
|
|
|
|
|
- throw new Exception('unable to write to file ' . $file, 11);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
/**
|
|
/**
|
|
|
* Convert paste id to storage path.
|
|
* Convert paste id to storage path.
|
|
|
*
|
|
*
|
|
@@ -338,8 +300,10 @@ class Filesystem extends AbstractData
|
|
|
*/
|
|
*/
|
|
|
private static function _dataid2path($dataid)
|
|
private static function _dataid2path($dataid)
|
|
|
{
|
|
{
|
|
|
- return self::$_dir . substr($dataid, 0, 2) . DIRECTORY_SEPARATOR .
|
|
|
|
|
- substr($dataid, 2, 2) . DIRECTORY_SEPARATOR;
|
|
|
|
|
|
|
+ return DataStore::getPath(
|
|
|
|
|
+ substr($dataid, 0, 2) . DIRECTORY_SEPARATOR .
|
|
|
|
|
+ substr($dataid, 2, 2) . DIRECTORY_SEPARATOR
|
|
|
|
|
+ );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -369,7 +333,7 @@ class Filesystem extends AbstractData
|
|
|
private static function _isFirstLevelDir($element)
|
|
private static function _isFirstLevelDir($element)
|
|
|
{
|
|
{
|
|
|
return self::_isSecondLevelDir($element) &&
|
|
return self::_isSecondLevelDir($element) &&
|
|
|
- is_dir(self::$_dir . DIRECTORY_SEPARATOR . $element);
|
|
|
|
|
|
|
+ is_dir(DataStore::getPath($element));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|