|
@@ -10,12 +10,20 @@
|
|
|
* @version 0.22
|
|
* @version 0.22
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
|
|
+namespace PrivateBin\data;
|
|
|
|
|
+
|
|
|
|
|
+use Exception;
|
|
|
|
|
+use PDO;
|
|
|
|
|
+use PDOException;
|
|
|
|
|
+use PrivateBin\privatebin;
|
|
|
|
|
+use stdClass;
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* privatebin_db
|
|
* privatebin_db
|
|
|
*
|
|
*
|
|
|
* Model for DB access, implemented as a singleton.
|
|
* Model for DB access, implemented as a singleton.
|
|
|
*/
|
|
*/
|
|
|
-class privatebin_db extends privatebin_abstract
|
|
|
|
|
|
|
+class db extends AbstractData
|
|
|
{
|
|
{
|
|
|
/**
|
|
/**
|
|
|
* cache for select queries
|
|
* cache for select queries
|
|
@@ -63,14 +71,15 @@ class privatebin_db extends privatebin_abstract
|
|
|
public static function getInstance($options = null)
|
|
public static function getInstance($options = null)
|
|
|
{
|
|
{
|
|
|
// if needed initialize the singleton
|
|
// if needed initialize the singleton
|
|
|
- if(!(self::$_instance instanceof privatebin_db)) {
|
|
|
|
|
|
|
+ if (!(self::$_instance instanceof privatebin_db)) {
|
|
|
self::$_instance = new self;
|
|
self::$_instance = new self;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (is_array($options))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (is_array($options)) {
|
|
|
// set table prefix if given
|
|
// set table prefix if given
|
|
|
- if (array_key_exists('tbl', $options)) self::$_prefix = $options['tbl'];
|
|
|
|
|
|
|
+ if (array_key_exists('tbl', $options)) {
|
|
|
|
|
+ self::$_prefix = $options['tbl'];
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
// initialize the db connection with new options
|
|
// initialize the db connection with new options
|
|
|
if (
|
|
if (
|
|
@@ -78,8 +87,7 @@ class privatebin_db extends privatebin_abstract
|
|
|
array_key_exists('usr', $options) &&
|
|
array_key_exists('usr', $options) &&
|
|
|
array_key_exists('pwd', $options) &&
|
|
array_key_exists('pwd', $options) &&
|
|
|
array_key_exists('opt', $options)
|
|
array_key_exists('opt', $options)
|
|
|
- )
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ ) {
|
|
|
// set default options
|
|
// set default options
|
|
|
$options['opt'][PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
|
|
$options['opt'][PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
|
|
|
$options['opt'][PDO::ATTR_EMULATE_PREPARES] = false;
|
|
$options['opt'][PDO::ATTR_EMULATE_PREPARES] = false;
|
|
@@ -102,40 +110,34 @@ class privatebin_db extends privatebin_abstract
|
|
|
$tables = self::$_db->query($tableQuery)->fetchAll(PDO::FETCH_COLUMN, 0);
|
|
$tables = self::$_db->query($tableQuery)->fetchAll(PDO::FETCH_COLUMN, 0);
|
|
|
|
|
|
|
|
// create paste table if necessary
|
|
// create paste table if necessary
|
|
|
- if (!in_array(self::_sanitizeIdentifier('paste'), $tables))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (!in_array(self::_sanitizeIdentifier('paste'), $tables)) {
|
|
|
self::_createPasteTable();
|
|
self::_createPasteTable();
|
|
|
$db_tables_exist = false;
|
|
$db_tables_exist = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// create comment table if necessary
|
|
// create comment table if necessary
|
|
|
- if (!in_array(self::_sanitizeIdentifier('comment'), $tables))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (!in_array(self::_sanitizeIdentifier('comment'), $tables)) {
|
|
|
self::_createCommentTable();
|
|
self::_createCommentTable();
|
|
|
$db_tables_exist = false;
|
|
$db_tables_exist = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// create config table if necessary
|
|
// create config table if necessary
|
|
|
$db_version = privatebin::VERSION;
|
|
$db_version = privatebin::VERSION;
|
|
|
- if (!in_array(self::_sanitizeIdentifier('config'), $tables))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (!in_array(self::_sanitizeIdentifier('config'), $tables)) {
|
|
|
self::_createConfigTable();
|
|
self::_createConfigTable();
|
|
|
// if we only needed to create the config table, the DB is older then 0.22
|
|
// if we only needed to create the config table, the DB is older then 0.22
|
|
|
- if ($db_tables_exist) $db_version = '0.21';
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if ($db_tables_exist) {
|
|
|
|
|
+ $db_version = '0.21';
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
$db_version = self::_getConfig('VERSION');
|
|
$db_version = self::_getConfig('VERSION');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// update database structure if necessary
|
|
// update database structure if necessary
|
|
|
- if (version_compare($db_version, privatebin::VERSION, '<'))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (version_compare($db_version, privatebin::VERSION, '<')) {
|
|
|
self::_upgradeDatabase($db_version);
|
|
self::_upgradeDatabase($db_version);
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ } else {
|
|
|
throw new Exception(
|
|
throw new Exception(
|
|
|
'Missing configuration for key dsn, usr, pwd or opt in the section model_options, please check your configuration file', 6
|
|
'Missing configuration for key dsn, usr, pwd or opt in the section model_options, please check your configuration file', 6
|
|
|
);
|
|
);
|
|
@@ -158,7 +160,7 @@ class privatebin_db extends privatebin_abstract
|
|
|
if (
|
|
if (
|
|
|
array_key_exists($pasteid, self::$_cache)
|
|
array_key_exists($pasteid, self::$_cache)
|
|
|
) {
|
|
) {
|
|
|
- if(false !== self::$_cache[$pasteid]) {
|
|
|
|
|
|
|
+ if (false !== self::$_cache[$pasteid]) {
|
|
|
return false;
|
|
return false;
|
|
|
} else {
|
|
} else {
|
|
|
unset(self::$_cache[$pasteid]);
|
|
unset(self::$_cache[$pasteid]);
|
|
@@ -170,28 +172,23 @@ class privatebin_db extends privatebin_abstract
|
|
|
$meta = $paste['meta'];
|
|
$meta = $paste['meta'];
|
|
|
unset($meta['postdate']);
|
|
unset($meta['postdate']);
|
|
|
$expire_date = 0;
|
|
$expire_date = 0;
|
|
|
- if (array_key_exists('expire_date', $paste['meta']))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (array_key_exists('expire_date', $paste['meta'])) {
|
|
|
$expire_date = (int) $paste['meta']['expire_date'];
|
|
$expire_date = (int) $paste['meta']['expire_date'];
|
|
|
unset($meta['expire_date']);
|
|
unset($meta['expire_date']);
|
|
|
}
|
|
}
|
|
|
- if (array_key_exists('opendiscussion', $paste['meta']))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (array_key_exists('opendiscussion', $paste['meta'])) {
|
|
|
$opendiscussion = (bool) $paste['meta']['opendiscussion'];
|
|
$opendiscussion = (bool) $paste['meta']['opendiscussion'];
|
|
|
unset($meta['opendiscussion']);
|
|
unset($meta['opendiscussion']);
|
|
|
}
|
|
}
|
|
|
- if (array_key_exists('burnafterreading', $paste['meta']))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (array_key_exists('burnafterreading', $paste['meta'])) {
|
|
|
$burnafterreading = (bool) $paste['meta']['burnafterreading'];
|
|
$burnafterreading = (bool) $paste['meta']['burnafterreading'];
|
|
|
unset($meta['burnafterreading']);
|
|
unset($meta['burnafterreading']);
|
|
|
}
|
|
}
|
|
|
- if (array_key_exists('attachment', $paste['meta']))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (array_key_exists('attachment', $paste['meta'])) {
|
|
|
$attachment = $paste['meta']['attachment'];
|
|
$attachment = $paste['meta']['attachment'];
|
|
|
unset($meta['attachment']);
|
|
unset($meta['attachment']);
|
|
|
}
|
|
}
|
|
|
- if (array_key_exists('attachmentname', $paste['meta']))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (array_key_exists('attachmentname', $paste['meta'])) {
|
|
|
$attachmentname = $paste['meta']['attachmentname'];
|
|
$attachmentname = $paste['meta']['attachmentname'];
|
|
|
unset($meta['attachmentname']);
|
|
unset($meta['attachmentname']);
|
|
|
}
|
|
}
|
|
@@ -230,31 +227,29 @@ class privatebin_db extends privatebin_abstract
|
|
|
' WHERE dataid = ?', array($pasteid), true
|
|
' WHERE dataid = ?', array($pasteid), true
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
- if(false !== $paste) {
|
|
|
|
|
|
|
+ if (false !== $paste) {
|
|
|
// create object
|
|
// create object
|
|
|
self::$_cache[$pasteid] = new stdClass;
|
|
self::$_cache[$pasteid] = new stdClass;
|
|
|
self::$_cache[$pasteid]->data = $paste['data'];
|
|
self::$_cache[$pasteid]->data = $paste['data'];
|
|
|
|
|
|
|
|
$meta = json_decode($paste['meta']);
|
|
$meta = json_decode($paste['meta']);
|
|
|
- if (!is_object($meta)) $meta = new stdClass;
|
|
|
|
|
|
|
+ if (!is_object($meta)) {
|
|
|
|
|
+ $meta = new stdClass;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
// support older attachments
|
|
// support older attachments
|
|
|
- if (property_exists($meta, 'attachment'))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (property_exists($meta, 'attachment')) {
|
|
|
self::$_cache[$pasteid]->attachment = $meta->attachment;
|
|
self::$_cache[$pasteid]->attachment = $meta->attachment;
|
|
|
unset($meta->attachment);
|
|
unset($meta->attachment);
|
|
|
- if (property_exists($meta, 'attachmentname'))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (property_exists($meta, 'attachmentname')) {
|
|
|
self::$_cache[$pasteid]->attachmentname = $meta->attachmentname;
|
|
self::$_cache[$pasteid]->attachmentname = $meta->attachmentname;
|
|
|
unset($meta->attachmentname);
|
|
unset($meta->attachmentname);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
// support current attachments
|
|
// support current attachments
|
|
|
- elseif (array_key_exists('attachment', $paste) && strlen($paste['attachment']))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ elseif (array_key_exists('attachment', $paste) && strlen($paste['attachment'])) {
|
|
|
self::$_cache[$pasteid]->attachment = $paste['attachment'];
|
|
self::$_cache[$pasteid]->attachment = $paste['attachment'];
|
|
|
- if (array_key_exists('attachmentname', $paste) && strlen($paste['attachmentname']))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (array_key_exists('attachmentname', $paste) && strlen($paste['attachmentname'])) {
|
|
|
self::$_cache[$pasteid]->attachmentname = $paste['attachmentname'];
|
|
self::$_cache[$pasteid]->attachmentname = $paste['attachmentname'];
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -263,13 +258,19 @@ class privatebin_db extends privatebin_abstract
|
|
|
$expire_date = (int) $paste['expiredate'];
|
|
$expire_date = (int) $paste['expiredate'];
|
|
|
if (
|
|
if (
|
|
|
$expire_date > 0
|
|
$expire_date > 0
|
|
|
- ) self::$_cache[$pasteid]->meta->expire_date = $expire_date;
|
|
|
|
|
|
|
+ ) {
|
|
|
|
|
+ self::$_cache[$pasteid]->meta->expire_date = $expire_date;
|
|
|
|
|
+ }
|
|
|
if (
|
|
if (
|
|
|
$paste['opendiscussion']
|
|
$paste['opendiscussion']
|
|
|
- ) self::$_cache[$pasteid]->meta->opendiscussion = true;
|
|
|
|
|
|
|
+ ) {
|
|
|
|
|
+ self::$_cache[$pasteid]->meta->opendiscussion = true;
|
|
|
|
|
+ }
|
|
|
if (
|
|
if (
|
|
|
$paste['burnafterreading']
|
|
$paste['burnafterreading']
|
|
|
- ) self::$_cache[$pasteid]->meta->burnafterreading = true;
|
|
|
|
|
|
|
+ ) {
|
|
|
|
|
+ self::$_cache[$pasteid]->meta->burnafterreading = true;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -295,7 +296,9 @@ class privatebin_db extends privatebin_abstract
|
|
|
);
|
|
);
|
|
|
if (
|
|
if (
|
|
|
array_key_exists($pasteid, self::$_cache)
|
|
array_key_exists($pasteid, self::$_cache)
|
|
|
- ) unset(self::$_cache[$pasteid]);
|
|
|
|
|
|
|
+ ) {
|
|
|
|
|
+ unset(self::$_cache[$pasteid]);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -309,7 +312,9 @@ class privatebin_db extends privatebin_abstract
|
|
|
{
|
|
{
|
|
|
if (
|
|
if (
|
|
|
!array_key_exists($pasteid, self::$_cache)
|
|
!array_key_exists($pasteid, self::$_cache)
|
|
|
- ) self::$_cache[$pasteid] = $this->read($pasteid);
|
|
|
|
|
|
|
+ ) {
|
|
|
|
|
+ self::$_cache[$pasteid] = $this->read($pasteid);
|
|
|
|
|
+ }
|
|
|
return (bool) self::$_cache[$pasteid];
|
|
return (bool) self::$_cache[$pasteid];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -325,10 +330,8 @@ class privatebin_db extends privatebin_abstract
|
|
|
*/
|
|
*/
|
|
|
public function createComment($pasteid, $parentid, $commentid, $comment)
|
|
public function createComment($pasteid, $parentid, $commentid, $comment)
|
|
|
{
|
|
{
|
|
|
- foreach (array('nickname', 'vizhash') as $key)
|
|
|
|
|
- {
|
|
|
|
|
- if (!array_key_exists($key, $comment['meta']))
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ foreach (array('nickname', 'vizhash') as $key) {
|
|
|
|
|
+ if (!array_key_exists($key, $comment['meta'])) {
|
|
|
$comment['meta'][$key] = null;
|
|
$comment['meta'][$key] = null;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -363,10 +366,8 @@ class privatebin_db extends privatebin_abstract
|
|
|
|
|
|
|
|
// create comment list
|
|
// create comment list
|
|
|
$comments = array();
|
|
$comments = array();
|
|
|
- if (count($rows))
|
|
|
|
|
- {
|
|
|
|
|
- foreach ($rows as $row)
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (count($rows)) {
|
|
|
|
|
+ foreach ($rows as $row) {
|
|
|
$i = $this->getOpenSlot($comments, (int) $row['postdate']);
|
|
$i = $this->getOpenSlot($comments, (int) $row['postdate']);
|
|
|
$comments[$i] = new stdClass;
|
|
$comments[$i] = new stdClass;
|
|
|
$comments[$i]->id = $row['dataid'];
|
|
$comments[$i]->id = $row['dataid'];
|
|
@@ -374,10 +375,12 @@ class privatebin_db extends privatebin_abstract
|
|
|
$comments[$i]->data = $row['data'];
|
|
$comments[$i]->data = $row['data'];
|
|
|
$comments[$i]->meta = new stdClass;
|
|
$comments[$i]->meta = new stdClass;
|
|
|
$comments[$i]->meta->postdate = (int) $row['postdate'];
|
|
$comments[$i]->meta->postdate = (int) $row['postdate'];
|
|
|
- if (array_key_exists('nickname', $row) && !empty($row['nickname']))
|
|
|
|
|
|
|
+ if (array_key_exists('nickname', $row) && !empty($row['nickname'])) {
|
|
|
$comments[$i]->meta->nickname = $row['nickname'];
|
|
$comments[$i]->meta->nickname = $row['nickname'];
|
|
|
- if (array_key_exists('vizhash', $row) && !empty($row['vizhash']))
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ if (array_key_exists('vizhash', $row) && !empty($row['vizhash'])) {
|
|
|
$comments[$i]->meta->vizhash = $row['vizhash'];
|
|
$comments[$i]->meta->vizhash = $row['vizhash'];
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
ksort($comments);
|
|
ksort($comments);
|
|
|
}
|
|
}
|
|
@@ -416,10 +419,8 @@ class privatebin_db extends privatebin_abstract
|
|
|
'SELECT dataid FROM ' . self::_sanitizeIdentifier('paste') .
|
|
'SELECT dataid FROM ' . self::_sanitizeIdentifier('paste') .
|
|
|
' WHERE expiredate < ? LIMIT ?', array(time(), $batchsize)
|
|
' WHERE expiredate < ? LIMIT ?', array(time(), $batchsize)
|
|
|
);
|
|
);
|
|
|
- if (count($rows))
|
|
|
|
|
- {
|
|
|
|
|
- foreach ($rows as $row)
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (count($rows)) {
|
|
|
|
|
+ foreach ($rows as $row) {
|
|
|
$pastes[] = $row['dataid'];
|
|
$pastes[] = $row['dataid'];
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -477,8 +478,7 @@ class privatebin_db extends privatebin_abstract
|
|
|
*/
|
|
*/
|
|
|
private static function _getTableQuery($type)
|
|
private static function _getTableQuery($type)
|
|
|
{
|
|
{
|
|
|
- switch($type)
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ switch ($type) {
|
|
|
case 'ibm':
|
|
case 'ibm':
|
|
|
$sql = 'SELECT tabname FROM SYSCAT.TABLES ';
|
|
$sql = 'SELECT tabname FROM SYSCAT.TABLES ';
|
|
|
break;
|
|
break;
|
|
@@ -551,12 +551,9 @@ class privatebin_db extends privatebin_abstract
|
|
|
private static function _getPrimaryKeyClauses($key = 'dataid')
|
|
private static function _getPrimaryKeyClauses($key = 'dataid')
|
|
|
{
|
|
{
|
|
|
$main_key = $after_key = '';
|
|
$main_key = $after_key = '';
|
|
|
- if (self::$_type === 'mysql')
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (self::$_type === 'mysql') {
|
|
|
$after_key = ", PRIMARY KEY ($key)";
|
|
$after_key = ", PRIMARY KEY ($key)";
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ } else {
|
|
|
$main_key = ' PRIMARY KEY';
|
|
$main_key = ' PRIMARY KEY';
|
|
|
}
|
|
}
|
|
|
return array($main_key, $after_key);
|
|
return array($main_key, $after_key);
|
|
@@ -659,8 +656,7 @@ class privatebin_db extends privatebin_abstract
|
|
|
private static function _upgradeDatabase($oldversion)
|
|
private static function _upgradeDatabase($oldversion)
|
|
|
{
|
|
{
|
|
|
$dataType = self::$_type === 'pgsql' ? 'TEXT' : 'BLOB';
|
|
$dataType = self::$_type === 'pgsql' ? 'TEXT' : 'BLOB';
|
|
|
- switch ($oldversion)
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ switch ($oldversion) {
|
|
|
case '0.21':
|
|
case '0.21':
|
|
|
// create the meta column if necessary (pre 0.21 change)
|
|
// create the meta column if necessary (pre 0.21 change)
|
|
|
try {
|
|
try {
|
|
@@ -679,8 +675,7 @@ class privatebin_db extends privatebin_abstract
|
|
|
);
|
|
);
|
|
|
// SQLite doesn't support MODIFY, but it allows TEXT of similar
|
|
// SQLite doesn't support MODIFY, but it allows TEXT of similar
|
|
|
// size as BLOB, so there is no need to change it there
|
|
// size as BLOB, so there is no need to change it there
|
|
|
- if (self::$_type !== 'sqlite')
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ if (self::$_type !== 'sqlite') {
|
|
|
self::$_db->exec(
|
|
self::$_db->exec(
|
|
|
'ALTER TABLE ' . self::_sanitizeIdentifier('paste') .
|
|
'ALTER TABLE ' . self::_sanitizeIdentifier('paste') .
|
|
|
' ADD PRIMARY KEY (dataid), MODIFY COLUMN data $dataType;'
|
|
' ADD PRIMARY KEY (dataid), MODIFY COLUMN data $dataType;'
|
|
@@ -690,9 +685,7 @@ class privatebin_db extends privatebin_abstract
|
|
|
" ADD PRIMARY KEY (dataid), MODIFY COLUMN data $dataType, " .
|
|
" ADD PRIMARY KEY (dataid), MODIFY COLUMN data $dataType, " .
|
|
|
"MODIFY COLUMN nickname $dataType, MODIFY COLUMN vizhash $dataType;"
|
|
"MODIFY COLUMN nickname $dataType, MODIFY COLUMN vizhash $dataType;"
|
|
|
);
|
|
);
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
|
|
+ } else {
|
|
|
self::$_db->exec(
|
|
self::$_db->exec(
|
|
|
'CREATE UNIQUE INDEX IF NOT EXISTS paste_dataid ON ' .
|
|
'CREATE UNIQUE INDEX IF NOT EXISTS paste_dataid ON ' .
|
|
|
self::_sanitizeIdentifier('paste') . '(dataid);'
|
|
self::_sanitizeIdentifier('paste') . '(dataid);'
|