added listing archiving-and-restore function (vandalism protection), and ...
- added log-picture removal on log deletion (bugfix) - block deletion of user accounts if archived logs or cache reports exist - show number of archived logs and cache reports in adminuser interface - improved cache description deletion confirmation message
This commit is contained in:
@@ -201,7 +201,7 @@
|
||||
else if ((substr($sql, $sqlpos - $arglength - 1, 1) == '`') && (substr($sql, $sqlpos + 1, 1) == '`'))
|
||||
$filtered_sql .= sql_escape_backtick($args[$arg]);
|
||||
else
|
||||
sql_error();
|
||||
sql_error($sql);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -258,7 +258,7 @@
|
||||
$filtered_sql .= '`';
|
||||
}
|
||||
else
|
||||
sql_error();
|
||||
sql_error($sql);
|
||||
|
||||
$sqlpos = $nextarg + $arglength + 1;
|
||||
}
|
||||
@@ -302,7 +302,7 @@
|
||||
$result = $sqldebugger->execute($filtered_sql, $dblink, ($dblink===$db['dblink_slave']), $db['slave_server']);
|
||||
if ($result === false)
|
||||
{
|
||||
sql_error();
|
||||
sql_error($filtered_sql);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -318,7 +318,7 @@
|
||||
$result = @mysql_query($filtered_sql, $dblink);
|
||||
if ($result === false)
|
||||
{
|
||||
sql_error();
|
||||
sql_error($filtered_sql);
|
||||
}
|
||||
|
||||
if ($opt['db']['warn']['time'] > 0)
|
||||
@@ -876,7 +876,7 @@
|
||||
$db['dblink_slave'] = false;
|
||||
}
|
||||
|
||||
function sql_error()
|
||||
function sql_error($sqlstatement="")
|
||||
{
|
||||
global $tpl, $opt, $db;
|
||||
global $bSmartyNoTranslate;
|
||||
@@ -888,6 +888,8 @@
|
||||
|
||||
$errno = mysql_errno();
|
||||
$error = mysql_error();
|
||||
if ($sqlstatement != "")
|
||||
$error .= "\n\nSQL statement: " . $sqlstatement;
|
||||
|
||||
if ($db['connected'] == false)
|
||||
$bSmartyNoTranslate = true;
|
||||
@@ -902,7 +904,7 @@
|
||||
$mail->name = 'sql_error';
|
||||
|
||||
$mail->assign('errno', $errno);
|
||||
$mail->assign('error', $error);
|
||||
$mail->assign('error', str_replace("\n","\r\n",$error));
|
||||
$mail->assign('trace', print_r(debug_backtrace(), true));
|
||||
|
||||
$mail->send();
|
||||
@@ -914,14 +916,14 @@
|
||||
if (isset($tpl))
|
||||
{
|
||||
if ($opt['db']['error']['display'] == true)
|
||||
$tpl->error('MySQL error' . ' (' . $errno . '): ' . $error);
|
||||
$tpl->error('MySQL error (' . $errno . '): ' . $error);
|
||||
else
|
||||
$tpl->error('A database command could not be performed.');
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($opt['db']['error']['display'] == true)
|
||||
die('<html><body>' . htmlspecialchars('MySQL error (' .$errno . '): ' . $error) . '</body></html>');
|
||||
die('<html><body>' . htmlspecialchars('MySQL error (' .$errno . '): ' . str_replace("\n,","<br />", $error)) . '</body></html>');
|
||||
else
|
||||
die('<html><body>A database command could not be performed</body></html>');
|
||||
}
|
||||
|
||||
@@ -146,7 +146,6 @@ class cachelog
|
||||
{
|
||||
return $this->reCacheLog->setValue('text_htmledit', $value);
|
||||
}
|
||||
|
||||
function getUUID()
|
||||
{
|
||||
return $this->reCacheLog->getValue('uuid');
|
||||
@@ -168,6 +167,15 @@ class cachelog
|
||||
return $this->reCacheLog->setValue('node', $value);
|
||||
}
|
||||
|
||||
function getOwnerNotified()
|
||||
{
|
||||
return $this->reCacheLog->getValue('owner_notified') != 0;
|
||||
}
|
||||
function setOwnerNotified($value)
|
||||
{
|
||||
return $this->reCacheLog->setValue('owner_notified', $value ? 1 : 0);
|
||||
}
|
||||
|
||||
function getAnyChanged()
|
||||
{
|
||||
return $this->reCacheLog->getAnyChanged();
|
||||
@@ -177,7 +185,18 @@ class cachelog
|
||||
function save()
|
||||
{
|
||||
sql_slave_exclude();
|
||||
return $this->reCacheLog->save();
|
||||
$saved = $this->reCacheLog->save();
|
||||
if ($saved && $this->nLogId == ID_NEW)
|
||||
$this->nLogId = $this->reCacheLog->getValue('id');
|
||||
return $saved;
|
||||
}
|
||||
|
||||
function updatePictureStat()
|
||||
{
|
||||
sql("UPDATE `cache_logs` SET `picture` =
|
||||
(SELECT COUNT(*) FROM `pictures` WHERE `object_type`=1 AND `object_id`='&1')
|
||||
WHERE `id`= '&1'",
|
||||
$this->getLogId());
|
||||
}
|
||||
|
||||
function allowView()
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
define('ADMIN_MAINTAINANCE', 2); // check table etc.
|
||||
define('ADMIN_USER', 4); // drop users, caches etc.
|
||||
define('ADMIN_NEWS', 8); // approve news entries
|
||||
define('ADMIN_RESTORE', 16); // restore vandalized listings
|
||||
define('ADMIN_ROOT', 128 | 127); // root + all previous rights
|
||||
|
||||
define('ATTRIB_SELECTED', 1);
|
||||
|
||||
@@ -93,7 +93,7 @@ class picture
|
||||
return false;
|
||||
|
||||
$sExtension = mb_strtolower(substr($sFilename, strrpos($sFilename, '.') + 1));
|
||||
|
||||
|
||||
if (strpos(';' . $opt['logic']['pictures']['extensions'] . ';', ';' . $sExtension . ';') !== false)
|
||||
return true;
|
||||
else
|
||||
@@ -108,13 +108,15 @@ class picture
|
||||
return;
|
||||
if (strpos($sFilename, '.') === false)
|
||||
return;
|
||||
|
||||
$sExtension = mb_strtolower(substr($sFilename, strrpos($sFilename, '.') + 1));
|
||||
$this->sFileExtension = $sExtension;
|
||||
|
||||
$sUUID = $this->getUUID();
|
||||
|
||||
$this->sFileExtension = $sExtension;
|
||||
$this->setUrl($opt['logic']['pictures']['url'] . $sUUID . '.' . $sExtension);
|
||||
//$this->setThumbUrl($opt['logic']['pictures']['thumb_url'] . substr($sUUID, 0, 1) . '/' . substr($sUUID, 1, 1) . '/' . $sUUID . '.' . $sExtension);
|
||||
|
||||
$this->bFilenamesSet = true;
|
||||
}
|
||||
|
||||
@@ -123,17 +125,51 @@ class picture
|
||||
return $this->nPictureId;
|
||||
}
|
||||
|
||||
function delete()
|
||||
private function setArchiveFlag($bRestoring, $original_id=0)
|
||||
{
|
||||
global $opt;
|
||||
global $login;
|
||||
|
||||
// delete record, image and thumb
|
||||
@unlink($this->getFilename());
|
||||
@unlink($this->getThumbFilename());
|
||||
// This function determines if an insert, update oder deletion at pictures table
|
||||
// ist to be recorded for vandalism recovery, depending on WHO OR WHY the
|
||||
// operation is done. Other conditions, depending on the data, are handled
|
||||
// by triggers.
|
||||
//
|
||||
// Data is passed by ugly global DB variables, so try call this function as
|
||||
// close before the targetet DB operation as possible.
|
||||
|
||||
sql("DELETE FROM `pictures` WHERE `id`='&1'", $this->nPictureId);
|
||||
if ($this->getObjectType() == 1)
|
||||
{
|
||||
/*
|
||||
$owner_id = sql_value("SELECT `user_id` FROM `caches` WHERE `cache_id`=
|
||||
IFNULL((SELECT `cache_id` FROM `cache_logs` WHERE `id`='&1'),
|
||||
(SELECT `cache_id` FROM `cache_logs_archived` WHERE `id`='&1'))",
|
||||
0, $this->getObjectId());
|
||||
*/
|
||||
$logger_id = sql_value("SELECT
|
||||
IFNULL((SELECT `user_id` FROM `cache_logs` WHERE `id`='&1'),
|
||||
(SELECT `user_id` FROM `cache_logs_archived` WHERE `id`='&1'))",
|
||||
0, $this->getObjectId());
|
||||
|
||||
return true;
|
||||
$archive = ($bRestoring || $login->userid != $logger_id);
|
||||
}
|
||||
else
|
||||
$archive = true;
|
||||
|
||||
sql("SET @archive_picop=" . ($archive ? "TRUE" : "FALSE"));
|
||||
sql_slave("SET @archive_picop=" . ($archive ? "TRUE" : "FALSE"));
|
||||
|
||||
sql("SET @original_picid='&1'", $original_id);
|
||||
sql_slave("SET @original_picid='&1'", $original_id);
|
||||
|
||||
// @archive_picop and @original_picid are evaluated by trigger functions
|
||||
}
|
||||
|
||||
private function resetArchiveFlag()
|
||||
{
|
||||
sql("SET @archive_picop=FALSE");
|
||||
sql("SET @original_picid=0");
|
||||
sql_slave("SET @archive_picop=FALSE");
|
||||
sql_slave("SET @original_picid=0");
|
||||
}
|
||||
|
||||
function getUrl()
|
||||
@@ -179,6 +215,14 @@ class picture
|
||||
{
|
||||
return $this->rePicture->setValue('local', $value ? 1 : 0);
|
||||
}
|
||||
function getUnknownFormat()
|
||||
{
|
||||
return $this->rePicture->getValue('unknown_format')!=0;
|
||||
}
|
||||
function setUnknownFormat($value)
|
||||
{
|
||||
return $this->rePicture->setValue('unknown_format', $value ? 1 : 0);
|
||||
}
|
||||
function getDisplay()
|
||||
{
|
||||
return $this->rePicture->getValue('display')!=0;
|
||||
@@ -197,18 +241,18 @@ class picture
|
||||
}
|
||||
function getFilename()
|
||||
{
|
||||
// works intendently before bFilenameSet == true !
|
||||
global $opt;
|
||||
|
||||
if (mb_substr($opt['logic']['pictures']['dir'], -1, 1) != '/')
|
||||
$opt['logic']['pictures']['dir'] .= '/';
|
||||
|
||||
$uuid = $this->getUUID();
|
||||
$url = $this->getUrl();
|
||||
$fna = mb_split('\\.', $url);
|
||||
$extension = mb_strtolower($fna[count($fna) - 1]);
|
||||
|
||||
return $opt['logic']['pictures']['dir'] . $uuid . '.' . $extension;
|
||||
$fna = mb_split('\\/', $url);
|
||||
|
||||
return $opt['logic']['pictures']['dir'] . end($fna);
|
||||
}
|
||||
|
||||
function getThumbFilename()
|
||||
{
|
||||
global $opt;
|
||||
@@ -216,16 +260,16 @@ class picture
|
||||
if (mb_substr($opt['logic']['pictures']['thumb_dir'], -1, 1) != '/')
|
||||
$opt['logic']['pictures']['thumb_dir'] .= '/';
|
||||
|
||||
$uuid = $this->getUUID();
|
||||
$url = $this->getUrl();
|
||||
$fna = mb_split('\\.', $url);
|
||||
$extension = mb_strtolower($fna[count($fna) - 1]);
|
||||
$fna = mb_split('\\/', $url);
|
||||
$filename = end($fna);
|
||||
|
||||
$dir1 = mb_strtoupper(mb_substr($uuid, 0, 1));
|
||||
$dir2 = mb_strtoupper(mb_substr($uuid, 1, 1));
|
||||
$dir1 = mb_strtoupper(mb_substr($filename, 0, 1));
|
||||
$dir2 = mb_strtoupper(mb_substr($filename, 1, 1));
|
||||
|
||||
return $opt['logic']['pictures']['thumb_dir'] . $dir1 . '/' . $dir2 . '/' . $uuid . '.' . $extension;
|
||||
return $opt['logic']['pictures']['thumb_dir'] . $dir1 . '/' . $dir2 . '/' . $filename;
|
||||
}
|
||||
|
||||
function getLogId()
|
||||
{
|
||||
if ($this->getObjectType() == OBJECT_CACHELOG)
|
||||
@@ -311,13 +355,29 @@ class picture
|
||||
return $this->rePicture->getAnyChanged();
|
||||
}
|
||||
|
||||
// return if successfull (with insert)
|
||||
function save()
|
||||
// return true if successful (with insert)
|
||||
function save($restore=false, $original_id=0, $original_url="")
|
||||
{
|
||||
$undelete = ($original_id != 0);
|
||||
|
||||
if ($undelete)
|
||||
if ($this->bFilenamesSet == true)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
// restore picture file
|
||||
$this->setUrl($original_url); // set the url, so that we can
|
||||
$filename = $this->getFilename(); // .. retreive the file path+name
|
||||
$this->setFilenames($filename); // now set url(s) from the new uuid
|
||||
@rename($this->deleted_filename($filename), $this->getFilename());
|
||||
}
|
||||
|
||||
if ($this->bFilenamesSet == false)
|
||||
return false;
|
||||
|
||||
$this->setArchiveFlag($restore, $original_id);
|
||||
$bRetVal = $this->rePicture->save();
|
||||
$this->resetArchiveFlag();
|
||||
|
||||
if ($bRetVal)
|
||||
{
|
||||
@@ -331,6 +391,43 @@ class picture
|
||||
return $bRetVal;
|
||||
}
|
||||
|
||||
function delete($restore=false)
|
||||
{
|
||||
// see also removelog.php, 'remove log pictures'
|
||||
|
||||
global $opt;
|
||||
|
||||
// delete record, image and thumb
|
||||
$this->setArchiveFlag($restore);
|
||||
sql("DELETE FROM `pictures` WHERE `id`='&1'", $this->nPictureId);
|
||||
$this->resetArchiveFlag();
|
||||
|
||||
// archive picture if picture record has been archived
|
||||
if (sql_value("SELECT `id` FROM `pictures_modified` WHERE `id`='&1'",
|
||||
0, $this->getPictureId()) != 0)
|
||||
{
|
||||
$filename = $this->getFilename();
|
||||
@rename($filename, $this->deleted_filename($filename));
|
||||
}
|
||||
else
|
||||
@unlink($filename);
|
||||
|
||||
@unlink($this->getThumbFilename());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function deleted_filename($filename)
|
||||
{
|
||||
$fna = mb_split('\\/',$filename);
|
||||
$fna[] = end($fna);
|
||||
$fna[count($fna)-2] = 'deleted';
|
||||
$dp = "";
|
||||
foreach ($fna as $fp)
|
||||
$dp .= "/" . $fp;
|
||||
return substr($dp,1);
|
||||
}
|
||||
|
||||
function allowEdit()
|
||||
{
|
||||
global $login;
|
||||
|
||||
@@ -880,6 +880,9 @@ class user
|
||||
sql_free_result($rsp);
|
||||
}
|
||||
sql_free_result($rs);
|
||||
|
||||
// discard achived logs' texts
|
||||
sql("UPDATE `cache_logs_archived` SET `text`='' WHERE `user_id`='&1'", $this->getUserId());
|
||||
|
||||
// success
|
||||
return true;
|
||||
@@ -1130,13 +1133,12 @@ class user
|
||||
if ($login->userid != $this->nUserId && ($login->admin & ADMIN_USER) != ADMIN_USER)
|
||||
return false;
|
||||
|
||||
if (sql_value("SELECT COUNT(*) FROM `caches` WHERE `user_id`='&1'", 0, $this->nUserId) > 0)
|
||||
return false;
|
||||
|
||||
if (sql_value("SELECT COUNT(*) FROM `cache_logs` WHERE `user_id`='&1'", 0, $this->nUserId) > 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return
|
||||
sql_value("SELECT COUNT(*) FROM `caches` WHERE `user_id`='&1'", 0, $this->nUserId)
|
||||
+ sql_value("SELECT COUNT(*) FROM `cache_logs` WHERE `user_id`='&1'", 0, $this->nUserId)
|
||||
+ sql_value("SELECT COUNT(*) FROM `cache_logs_archived` WHERE `user_id`='&1'", 0, $this->nUserId)
|
||||
+ sql_value("SELECT COUNT(*) FROM `cache_reports` WHERE `userid`='&1'", 0, $this->nUserId)
|
||||
== 0;
|
||||
}
|
||||
|
||||
function delete()
|
||||
@@ -1160,13 +1162,7 @@ class user
|
||||
serialize($backup));
|
||||
|
||||
sql("DELETE FROM `user` WHERE `user_id`='&1'", $this->nUserId);
|
||||
sql("DELETE FROM `cache_adoption` WHERE `user_id`='&1'", $this->nUserId);
|
||||
sql("DELETE FROM `cache_ignore` WHERE `user_id`='&1'", $this->nUserId);
|
||||
sql("DELETE FROM `cache_rating` WHERE `user_id`='&1'", $this->nUserId);
|
||||
sql("DELETE FROM `cache_watches` WHERE `user_id`='&1'", $this->nUserId);
|
||||
sql("DELETE FROM `stat_user` WHERE `user_id`='&1'", $this->nUserId);
|
||||
sql("DELETE FROM `user_options` WHERE `user_id`='&1'", $this->nUserId);
|
||||
sql("DELETE FROM `watches_waiting` WHERE `user_id`='&1'", $this->nUserId);
|
||||
// all data in depending tables is cleared via trigger
|
||||
|
||||
$this->reload();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user