Michael Save
12 years ago
15 changed files with 6754 additions and 6668 deletions
@ -1,107 +1,111 @@ |
|||||
<?php |
<?php |
||||
if($_SERVER['SCRIPT_FILENAME'] == str_replace('\\', '/', __FILE__)) { |
|
||||
// You cannot request this file directly. |
/* |
||||
header('Location: ../', true, 302); |
* Copyright (c) 2010-2012 Tinyboard Development Group |
||||
exit; |
*/ |
||||
} |
|
||||
|
if(realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) { |
||||
|
// You cannot request this file directly. |
||||
|
exit; |
||||
|
} |
||||
|
|
||||
|
class PreparedQueryDebug { |
||||
|
protected $query; |
||||
|
|
||||
class PreparedQueryDebug { |
public function __construct($query) { |
||||
protected $query; |
global $pdo; |
||||
|
$query = preg_replace("/[\n\t]+/", ' ', $query); |
||||
|
|
||||
public function __construct($query) { |
$this->query = $pdo->prepare($query); |
||||
global $pdo; |
|
||||
$query = preg_replace("/[\n\t]+/", ' ', $query); |
|
||||
|
|
||||
$this->query = $pdo->prepare($query); |
|
||||
} |
|
||||
public function __call($function, $args) { |
|
||||
global $config, $debug; |
|
||||
|
|
||||
if($config['debug'] && $function == 'execute') { |
|
||||
$start = microtime(true); |
|
||||
} |
|
||||
|
|
||||
$return = call_user_func_array(Array($this->query, $function), $args); |
|
||||
|
|
||||
if($config['debug'] && $function == 'execute') { |
|
||||
$time = round((microtime(true) - $start) * 1000, 2) . 'ms'; |
|
||||
|
|
||||
$debug['sql'][] = Array( |
|
||||
'query' => $this->query->queryString, |
|
||||
'rows' => $this->query->rowCount(), |
|
||||
'time' => '~' . $time |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
return $return; |
|
||||
} |
|
||||
} |
} |
||||
|
public function __call($function, $args) { |
||||
function sql_open() { |
global $config, $debug; |
||||
global $pdo, $config; |
|
||||
if($pdo) return true; |
|
||||
|
|
||||
$dsn = $config['db']['type'] . ':host=' . $config['db']['server'] . ';dbname=' . $config['db']['database']; |
if($config['debug'] && $function == 'execute') { |
||||
if(!empty($config['db']['dsn'])) |
$start = microtime(true); |
||||
$dsn .= ';' . $config['db']['dsn']; |
|
||||
try { |
|
||||
$options = Array(PDO::ATTR_TIMEOUT => $config['db']['timeout']); |
|
||||
$options = Array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'); |
|
||||
if($config['db']['persistent']) |
|
||||
$options[PDO::ATTR_PERSISTENT] = true; |
|
||||
return $pdo = new PDO($dsn, $config['db']['user'], $config['db']['password'], $options); |
|
||||
} catch(PDOException $e) { |
|
||||
$message = $e->getMessage(); |
|
||||
|
|
||||
// Remove any sensitive information |
|
||||
$message = str_replace($config['db']['user'], '<em>hidden</em>', $message); |
|
||||
$message = str_replace($config['db']['password'], '<em>hidden</em>', $message); |
|
||||
|
|
||||
// Print error |
|
||||
error('Database error: ' . $message); |
|
||||
} |
} |
||||
} |
|
||||
|
|
||||
function prepare($query) { |
|
||||
global $pdo, $debug, $config; |
|
||||
|
|
||||
sql_open(); |
|
||||
|
|
||||
if($config['debug']) |
$return = call_user_func_array(array($this->query, $function), $args); |
||||
return new PreparedQueryDebug($query); |
|
||||
return $pdo->prepare($query); |
|
||||
} |
|
||||
|
|
||||
function query($query) { |
|
||||
global $pdo, $debug, $config; |
|
||||
|
|
||||
sql_open(); |
if($config['debug'] && $function == 'execute') { |
||||
|
|
||||
if($config['debug']) { |
|
||||
$start = microtime(true); |
|
||||
$query = $pdo->query($query); |
|
||||
if(!$query) |
|
||||
return false; |
|
||||
$time = round((microtime(true) - $start) * 1000, 2) . 'ms'; |
$time = round((microtime(true) - $start) * 1000, 2) . 'ms'; |
||||
|
|
||||
$debug['sql'][] = Array( |
$debug['sql'][] = Array( |
||||
'query' => $query->queryString, |
'query' => $this->query->queryString, |
||||
'rows' => $query->rowCount(), |
'rows' => $this->query->rowCount(), |
||||
'time' => '~' . $time |
'time' => '~' . $time |
||||
); |
); |
||||
return $query; |
|
||||
} else { |
|
||||
return $pdo->query($query); |
|
||||
} |
} |
||||
|
|
||||
|
return $return; |
||||
} |
} |
||||
|
} |
||||
|
|
||||
|
function sql_open() { |
||||
|
global $pdo, $config; |
||||
|
if($pdo) return true; |
||||
|
|
||||
function db_error($PDOStatement=null) { |
$dsn = $config['db']['type'] . ':host=' . $config['db']['server'] . ';dbname=' . $config['db']['database']; |
||||
global $pdo; |
if(!empty($config['db']['dsn'])) |
||||
if(isset($PDOStatement)) { |
$dsn .= ';' . $config['db']['dsn']; |
||||
$err = $PDOStatement->errorInfo(); |
try { |
||||
return $err[2]; |
$options = Array(PDO::ATTR_TIMEOUT => $config['db']['timeout']); |
||||
} else { |
$options = Array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'); |
||||
$err = $pdo->errorInfo(); |
if($config['db']['persistent']) |
||||
return $err[2]; |
$options[PDO::ATTR_PERSISTENT] = true; |
||||
} |
return $pdo = new PDO($dsn, $config['db']['user'], $config['db']['password'], $options); |
||||
|
} catch(PDOException $e) { |
||||
|
$message = $e->getMessage(); |
||||
|
|
||||
|
// Remove any sensitive information |
||||
|
$message = str_replace($config['db']['user'], '<em>hidden</em>', $message); |
||||
|
$message = str_replace($config['db']['password'], '<em>hidden</em>', $message); |
||||
|
|
||||
|
// Print error |
||||
|
error('Database error: ' . $message); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function prepare($query) { |
||||
|
global $pdo, $debug, $config; |
||||
|
|
||||
|
sql_open(); |
||||
|
|
||||
|
if($config['debug']) |
||||
|
return new PreparedQueryDebug($query); |
||||
|
return $pdo->prepare($query); |
||||
|
} |
||||
|
|
||||
|
function query($query) { |
||||
|
global $pdo, $debug, $config; |
||||
|
|
||||
|
sql_open(); |
||||
|
|
||||
|
if($config['debug']) { |
||||
|
$start = microtime(true); |
||||
|
$query = $pdo->query($query); |
||||
|
if(!$query) |
||||
|
return false; |
||||
|
$time = round((microtime(true) - $start) * 1000, 2) . 'ms'; |
||||
|
$debug['sql'][] = Array( |
||||
|
'query' => $query->queryString, |
||||
|
'rows' => $query->rowCount(), |
||||
|
'time' => '~' . $time |
||||
|
); |
||||
|
return $query; |
||||
|
} else { |
||||
|
return $pdo->query($query); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function db_error($PDOStatement=null) { |
||||
|
global $pdo; |
||||
|
if(isset($PDOStatement)) { |
||||
|
$err = $PDOStatement->errorInfo(); |
||||
|
return $err[2]; |
||||
|
} else { |
||||
|
$err = $pdo->errorInfo(); |
||||
|
return $err[2]; |
||||
} |
} |
||||
?> |
} |
||||
|
|
||||
|
@ -1,445 +1,441 @@ |
|||||
<?php |
<?php |
||||
if($_SERVER['SCRIPT_FILENAME'] == str_replace('\\', '/', __FILE__)) { |
|
||||
// You cannot request this file directly. |
/* |
||||
header('Location: ../', true, 302); |
* Copyright (c) 2010-2012 Tinyboard Development Group |
||||
exit; |
*/ |
||||
|
|
||||
|
if(realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) { |
||||
|
// You cannot request this file directly. |
||||
|
exit; |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
[email protected] |
||||
|
http://www.php.net/manual/en/function.filesize.php#100097 |
||||
|
*/ |
||||
|
function format_bytes($size) { |
||||
|
$units = array(' B', ' KB', ' MB', ' GB', ' TB'); |
||||
|
for ($i = 0; $size >= 1024 && $i < 4; $i++) $size /= 1024; |
||||
|
return round($size, 2).$units[$i]; |
||||
|
} |
||||
|
|
||||
|
function doBoardListPart($list, $root) { |
||||
|
global $config; |
||||
|
|
||||
|
$body = ''; |
||||
|
foreach($list as $board) { |
||||
|
if(is_array($board)) |
||||
|
$body .= ' [' . doBoardListPart($board, $root) . '] '; |
||||
|
else { |
||||
|
if(($key = array_search($board, $list)) && gettype($key) == 'string') { |
||||
|
$body .= ' <a href="' . $board . '">' . $key . '</a> /'; |
||||
|
} else { |
||||
|
$body .= ' <a href="' . $root . $board . '/' . $config['file_index'] . '">' . $board . '</a> /'; |
||||
|
} |
||||
|
} |
||||
} |
} |
||||
|
$body = preg_replace('/\/$/', '', $body); |
||||
|
|
||||
/* |
return $body; |
||||
Stuff to help with the display. |
} |
||||
*/ |
|
||||
|
function createBoardlist($mod=false) { |
||||
|
global $config; |
||||
|
|
||||
|
if(!isset($config['boards'])) return Array('top'=>'','bottom'=>''); |
||||
|
|
||||
/* |
$body = doBoardListPart($config['boards'], $mod?'?/':$config['root']); |
||||
[email protected] |
if(!preg_match('/\] $/', $body)) |
||||
http://www.php.net/manual/en/function.filesize.php#100097 |
$body = '[' . $body . ']'; |
||||
*/ |
|
||||
function format_bytes($size) { |
|
||||
$units = array(' B', ' KB', ' MB', ' GB', ' TB'); |
|
||||
for ($i = 0; $size >= 1024 && $i < 4; $i++) $size /= 1024; |
|
||||
return round($size, 2).$units[$i]; |
|
||||
} |
|
||||
|
|
||||
function commaize($n) { |
$body = trim($body); |
||||
$n = strval($n); |
|
||||
return (intval($n) < 1000) ? $n : commaize(substr($n, 0, -3)) . ',' . substr($n, -3); |
|
||||
} |
|
||||
|
|
||||
function doBoardListPart($list, $root) { |
return Array( |
||||
global $config; |
'top' => '<div class="boardlist">' . $body . '</div>', |
||||
|
'bottom' => '<div class="boardlist bottom">' . $body . '</div>' |
||||
$body = ''; |
); |
||||
foreach($list as $board) { |
} |
||||
if(is_array($board)) |
|
||||
$body .= ' [' . doBoardListPart($board, $root) . '] '; |
function error($message, $priority = true) { |
||||
else { |
global $board, $mod, $config; |
||||
if(($key = array_search($board, $list)) && gettype($key) == 'string') { |
|
||||
$body .= ' <a href="' . $board . '">' . $key . '</a> /'; |
|
||||
} else { |
|
||||
$body .= ' <a href="' . $root . $board . '/' . $config['file_index'] . '">' . $board . '</a> /'; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
$body = preg_replace('/\/$/', '', $body); |
|
||||
|
|
||||
return $body; |
|
||||
} |
|
||||
|
|
||||
function createBoardlist($mod=false) { |
if($config['syslog'] && $priority !== false) { |
||||
global $config; |
// Use LOG_NOTICE instead of LOG_ERR or LOG_WARNING because most error message are not significant. |
||||
|
_syslog($priority !== true ? $priority : LOG_NOTICE, $message); |
||||
if(!isset($config['boards'])) return Array('top'=>'','bottom'=>''); |
|
||||
|
|
||||
$body = doBoardListPart($config['boards'], $mod?'?/':$config['root']); |
|
||||
if(!preg_match('/\] $/', $body)) |
|
||||
$body = '[' . $body . ']'; |
|
||||
|
|
||||
$body = trim($body); |
|
||||
|
|
||||
return Array( |
|
||||
'top' => '<div class="boardlist">' . $body . '</div>', |
|
||||
'bottom' => '<div class="boardlist bottom">' . $body . '</div>' |
|
||||
); |
|
||||
} |
} |
||||
|
|
||||
function error($message, $priority = true) { |
if(defined('STDIN')) { |
||||
global $board, $mod, $config; |
// Running from CLI |
||||
|
die('Error: ' . $message . "\n"); |
||||
if($config['syslog'] && $priority !== false) { |
|
||||
// Use LOG_NOTICE instead of LOG_ERR or LOG_WARNING because most error message are not significant. |
|
||||
_syslog($priority !== true ? $priority : LOG_NOTICE, $message); |
|
||||
} |
|
||||
|
|
||||
if(defined('STDIN')) { |
|
||||
// Running from CLI |
|
||||
die('Error: ' . $message . "\n"); |
|
||||
} |
|
||||
|
|
||||
die(Element('page.html', Array( |
|
||||
'config'=>$config, |
|
||||
'title'=>'Error', |
|
||||
'subtitle'=>'An error has occured.', |
|
||||
'body'=>'<center>' . |
|
||||
'<h2>' . _($message) . '</h2>' . |
|
||||
(isset($board) ? |
|
||||
"<p><a href=\"" . $config['root'] . |
|
||||
($mod ? $config['file_mod'] . '?/' : '') . |
|
||||
$board['dir'] . $config['file_index'] . "\">Go back</a>.</p>" : '') . |
|
||||
'</center>' |
|
||||
))); |
|
||||
} |
} |
||||
|
|
||||
function loginForm($error=false, $username=false, $redirect=false) { |
die(Element('page.html', Array( |
||||
global $config; |
'config'=>$config, |
||||
|
'title'=>'Error', |
||||
die(Element('page.html', Array( |
'subtitle'=>'An error has occured.', |
||||
'index'=>$config['root'], |
'body'=>'<center>' . |
||||
'title'=>_('Login'), |
'<h2>' . _($message) . '</h2>' . |
||||
|
(isset($board) ? |
||||
|
"<p><a href=\"" . $config['root'] . |
||||
|
($mod ? $config['file_mod'] . '?/' : '') . |
||||
|
$board['dir'] . $config['file_index'] . "\">Go back</a>.</p>" : '') . |
||||
|
'</center>' |
||||
|
))); |
||||
|
} |
||||
|
|
||||
|
function loginForm($error=false, $username=false, $redirect=false) { |
||||
|
global $config; |
||||
|
|
||||
|
die(Element('page.html', Array( |
||||
|
'index'=>$config['root'], |
||||
|
'title'=>_('Login'), |
||||
|
'config'=>$config, |
||||
|
'body'=>Element('login.html', Array( |
||||
'config'=>$config, |
'config'=>$config, |
||||
'body'=>Element('login.html', Array( |
'error'=>$error, |
||||
'config'=>$config, |
'username'=>utf8tohtml($username), |
||||
'error'=>$error, |
'redirect'=>$redirect |
||||
'username'=>utf8tohtml($username), |
|
||||
'redirect'=>$redirect |
|
||||
) |
|
||||
) |
) |
||||
))); |
) |
||||
|
))); |
||||
|
} |
||||
|
|
||||
|
function pm_snippet($body, $len=null) { |
||||
|
global $config; |
||||
|
|
||||
|
if(!isset($len)) |
||||
|
$len = &$config['mod']['snippet_length']; |
||||
|
|
||||
|
// Replace line breaks with some whitespace |
||||
|
$body = str_replace('<br/>', ' ', $body); |
||||
|
|
||||
|
// Strip tags |
||||
|
$body = strip_tags($body); |
||||
|
|
||||
|
// Unescape HTML characters, to avoid splitting them in half |
||||
|
$body = html_entity_decode($body, ENT_COMPAT, 'UTF-8'); |
||||
|
|
||||
|
// calculate strlen() so we can add "..." after if needed |
||||
|
$strlen = mb_strlen($body); |
||||
|
|
||||
|
$body = substr($body, 0, $len); |
||||
|
|
||||
|
// Re-escape the characters. |
||||
|
return '<em>' . utf8tohtml($body) . ($strlen > $len ? '…' : '') . '</em>'; |
||||
|
} |
||||
|
|
||||
|
function capcode($cap) { |
||||
|
global $config; |
||||
|
|
||||
|
if(!$cap) |
||||
|
return false; |
||||
|
|
||||
|
$capcode = Array(); |
||||
|
if(isset($config['custom_capcode'][$cap])) { |
||||
|
if(is_array($config['custom_capcode'][$cap])) { |
||||
|
$capcode['cap'] = sprintf($config['custom_capcode'][$cap][0], $cap); |
||||
|
if(isset($config['custom_capcode'][$cap][1])) |
||||
|
$capcode['name'] = $config['custom_capcode'][$cap][1]; |
||||
|
if(isset($config['custom_capcode'][$cap][2])) |
||||
|
$capcode['trip'] = $config['custom_capcode'][$cap][2]; |
||||
|
} else { |
||||
|
$capcode['cap'] = sprintf($config['custom_capcode'][$cap], $cap); |
||||
|
} |
||||
|
} else { |
||||
|
$capcode['cap'] = sprintf($config['capcode'], $cap); |
||||
} |
} |
||||
|
|
||||
function pm_snippet($body, $len=null) { |
return $capcode; |
||||
global $config; |
} |
||||
|
|
||||
if(!isset($len)) |
function truncate($body, $url, $max_lines = false, $max_chars = false) { |
||||
$len = &$config['mod']['snippet_length']; |
global $config; |
||||
|
|
||||
// Replace line breaks with some whitespace |
if($max_lines === false) |
||||
$body = str_replace('<br/>', ' ', $body); |
$max_lines = $config['body_truncate']; |
||||
|
if($max_chars === false) |
||||
// Strip tags |
$max_chars = $config['body_truncate_char']; |
||||
$body = strip_tags($body); |
$original_body = $body; |
||||
|
|
||||
// Unescape HTML characters, to avoid splitting them in half |
$lines = substr_count($body, '<br/>'); |
||||
$body = html_entity_decode($body, ENT_COMPAT, 'UTF-8'); |
|
||||
|
// Limit line count |
||||
// calculate strlen() so we can add "..." after if needed |
if($lines > $max_lines) { |
||||
$strlen = mb_strlen($body); |
if(preg_match('/(((.*?)<br\/>){' . $max_lines . '})/', $body, $m)) |
||||
|
$body = $m[0]; |
||||
$body = substr($body, 0, $len); |
|
||||
|
|
||||
// Re-escape the characters. |
|
||||
return '<em>' . utf8tohtml($body) . ($strlen > $len ? '…' : '') . '</em>'; |
|
||||
} |
} |
||||
|
|
||||
function capcode($cap) { |
$body = substr($body, 0, $max_chars); |
||||
global $config; |
|
||||
|
if($body != $original_body) { |
||||
if(!$cap) |
// Remove any corrupt tags at the end |
||||
return false; |
$body = preg_replace('/<([\w]+)?([^>]*)?$/', '', $body); |
||||
|
|
||||
$capcode = Array(); |
// Open tags |
||||
if(isset($config['custom_capcode'][$cap])) { |
if(preg_match_all('/<([\w]+)[^>]*>/', $body, $open_tags)) { |
||||
if(is_array($config['custom_capcode'][$cap])) { |
|
||||
$capcode['cap'] = sprintf($config['custom_capcode'][$cap][0], $cap); |
$tags = Array(); |
||||
if(isset($config['custom_capcode'][$cap][1])) |
for($x=0;$x<count($open_tags[0]);$x++) { |
||||
$capcode['name'] = $config['custom_capcode'][$cap][1]; |
if(!preg_match('/\/(\s+)?>$/', $open_tags[0][$x])) |
||||
if(isset($config['custom_capcode'][$cap][2])) |
$tags[] = $open_tags[1][$x]; |
||||
$capcode['trip'] = $config['custom_capcode'][$cap][2]; |
} |
||||
} else { |
|
||||
$capcode['cap'] = sprintf($config['custom_capcode'][$cap], $cap); |
// List successfully closed tags |
||||
|
if(preg_match_all('/(<\/([\w]+))>/', $body, $closed_tags)) { |
||||
|
for($x=0;$x<count($closed_tags[0]);$x++) { |
||||
|
unset($tags[array_search($closed_tags[2][$x], $tags)]); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// remove broken HTML entity at the end (if existent) |
||||
|
$body = preg_replace('/&[^;]+$/', '', $body); |
||||
|
|
||||
|
// Close any open tags |
||||
|
foreach($tags as &$tag) { |
||||
|
$body .= "</{$tag}>"; |
||||
} |
} |
||||
} else { |
} else { |
||||
$capcode['cap'] = sprintf($config['capcode'], $cap); |
// remove broken HTML entity at the end (if existent) |
||||
|
$body = preg_replace('/&[^;]+$/', '', $body); |
||||
} |
} |
||||
|
|
||||
return $capcode; |
$body .= '<span class="toolong">Post too long. Click <a href="' . $url . '">here</a> to view the full text.</span>'; |
||||
} |
} |
||||
|
|
||||
function truncate($body, $url, $max_lines = false, $max_chars = false) { |
return $body; |
||||
|
} |
||||
|
|
||||
|
function confirmLink($text, $title, $confirm, $href) { |
||||
|
global $config, $mod; |
||||
|
if($config['mod']['server-side_confirm']) |
||||
|
return '<a onclick="if(confirm(\'' . htmlentities(addslashes($confirm)) . '\')) document.location=\'?/' . htmlentities(addslashes($href)) . '\';return false;" title="' . htmlentities($title) . '" href="?/confirm/' . $href . '">' . $text . '</a>'; |
||||
|
else |
||||
|
return '<a onclick="return confirm(\'' . htmlentities(addslashes($confirm)) . '\')" title="' . htmlentities($title) . '" href="?/' . $href . '">' . $text . '</a>'; |
||||
|
} |
||||
|
|
||||
|
class Post { |
||||
|
public function __construct($id, $thread, $subject, $email, $name, $trip, $capcode, $body, $time, $thumb, $thumbx, $thumby, $file, $filex, $filey, $filesize, $filename, $ip, $embed, $root=null, $mod=false) { |
||||
global $config; |
global $config; |
||||
|
if(!isset($root)) |
||||
|
$root = &$config['root']; |
||||
|
|
||||
if($max_lines === false) |
$this->id = $id; |
||||
$max_lines = $config['body_truncate']; |
$this->thread = $thread; |
||||
if($max_chars === false) |
$this->subject = utf8tohtml($subject); |
||||
$max_chars = $config['body_truncate_char']; |
$this->email = $email; |
||||
$original_body = $body; |
$this->name = utf8tohtml($name); |
||||
|
$this->trip = $trip; |
||||
|
$this->capcode = $capcode; |
||||
|
$this->body = $body; |
||||
|
$this->time = $time; |
||||
|
$this->thumb = $thumb; |
||||
|
$this->thumbx = $thumbx; |
||||
|
$this->thumby = $thumby; |
||||
|
$this->file = $file; |
||||
|
$this->filex = $filex; |
||||
|
$this->filey = $filey; |
||||
|
$this->filesize = $filesize; |
||||
|
$this->filename = $filename; |
||||
|
$this->ip = $ip; |
||||
|
$this->embed = $embed; |
||||
|
$this->root = $root; |
||||
|
$this->mod = $mod; |
||||
|
|
||||
$lines = substr_count($body, '<br/>'); |
if($this->mod) |
||||
|
// Fix internal links |
||||
// Limit line count |
// Very complicated regex |
||||
if($lines > $max_lines) { |
$this->body = preg_replace( |
||||
if(preg_match('/(((.*?)<br\/>){' . $max_lines . '})/', $body, $m)) |
'/<a((([a-zA-Z]+="[^"]+")|[a-zA-Z]+=[a-zA-Z]+|\s)*)href="' . preg_quote($config['root'], '/') . '(' . sprintf(preg_quote($config['board_path'], '/'), '\w+') . ')/', |
||||
$body = $m[0]; |
'<a $1href="?/$4', |
||||
} |
$this->body |
||||
|
); |
||||
|
} |
||||
|
public function link($pre = '') { |
||||
|
global $config, $board; |
||||
|
|
||||
$body = substr($body, 0, $max_chars); |
return $this->root . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $this->thread) . '#' . $pre . $this->id; |
||||
|
} |
||||
|
public function postControls() { |
||||
|
global $board, $config; |
||||
|
|
||||
if($body != $original_body) { |
$built = ''; |
||||
// Remove any corrupt tags at the end |
if($this->mod) { |
||||
$body = preg_replace('/<([\w]+)?([^>]*)?$/', '', $body); |
// Mod controls (on posts) |
||||
|
|
||||
// Open tags |
// Delete |
||||
if(preg_match_all('/<([\w]+)[^>]*>/', $body, $open_tags)) { |
if(hasPermission($config['mod']['delete'], $board['uri'], $this->mod)) |
||||
|
$built .= ' ' . confirmLink($config['mod']['link_delete'], 'Delete', 'Are you sure you want to delete this?', $board['uri'] . '/delete/' . $this->id); |
||||
$tags = Array(); |
|
||||
for($x=0;$x<count($open_tags[0]);$x++) { |
// Delete all posts by IP |
||||
if(!preg_match('/\/(\s+)?>$/', $open_tags[0][$x])) |
if(hasPermission($config['mod']['deletebyip'], $board['uri'], $this->mod)) |
||||
$tags[] = $open_tags[1][$x]; |
$built .= ' ' . confirmLink($config['mod']['link_deletebyip'], 'Delete all posts by IP', 'Are you sure you want to delete all posts by this IP address?', $board['uri'] . '/deletebyip/' . $this->id); |
||||
} |
|
||||
|
// Delete all posts by IP (global) |
||||
// List successfully closed tags |
if(hasPermission($config['mod']['deletebyip_global'], $board['uri'], $this->mod)) |
||||
if(preg_match_all('/(<\/([\w]+))>/', $body, $closed_tags)) { |
$built .= ' ' . confirmLink($config['mod']['link_deletebyip_global'], 'Delete all posts by IP across all boards', 'Are you sure you want to delete all posts by this IP address, across all boards?', $board['uri'] . '/deletebyip/' . $this->id . '/global'); |
||||
for($x=0;$x<count($closed_tags[0]);$x++) { |
|
||||
unset($tags[array_search($closed_tags[2][$x], $tags)]); |
// Ban |
||||
} |
if(hasPermission($config['mod']['ban'], $board['uri'], $this->mod)) |
||||
} |
$built .= ' <a title="Ban" href="?/' . $board['uri'] . '/ban/' . $this->id . '">' . $config['mod']['link_ban'] . '</a>'; |
||||
|
|
||||
// remove broken HTML entity at the end (if existent) |
// Ban & Delete |
||||
$body = preg_replace('/&[^;]+$/', '', $body); |
if(hasPermission($config['mod']['bandelete'], $board['uri'], $this->mod)) |
||||
|
$built .= ' <a title="Ban & Delete" href="?/' . $board['uri'] . '/ban&delete/' . $this->id . '">' . $config['mod']['link_bandelete'] . '</a>'; |
||||
// Close any open tags |
|
||||
foreach($tags as &$tag) { |
|
||||
$body .= "</{$tag}>"; |
|
||||
} |
|
||||
} else { |
|
||||
// remove broken HTML entity at the end (if existent) |
|
||||
$body = preg_replace('/&[^;]+$/', '', $body); |
|
||||
} |
|
||||
|
|
||||
$body .= '<span class="toolong">Post too long. Click <a href="' . $url . '">here</a> to view the full text.</span>'; |
// Delete file (keep post) |
||||
|
if(!empty($this->file) && hasPermission($config['mod']['deletefile'], $board['uri'], $this->mod)) |
||||
|
$built .= ' <a title="Remove file" href="?/' . $board['uri'] . '/deletefile/' . $this->id . '">' . $config['mod']['link_deletefile'] . '</a>'; |
||||
|
|
||||
|
// Edit post |
||||
|
if(hasPermission($config['mod']['editpost'], $board['uri'], $this->mod)) |
||||
|
$built .= ' <a title="Edit post" href="?/' . $board['uri'] . '/edit/' . $this->id . '">' . $config['mod']['link_editpost'] . '</a>'; |
||||
|
|
||||
|
if(!empty($built)) |
||||
|
$built = '<span class="controls">' . $built . '</span>'; |
||||
} |
} |
||||
|
return $built; |
||||
return $body; |
|
||||
} |
} |
||||
|
|
||||
function confirmLink($text, $title, $confirm, $href) { |
public function build($index=false) { |
||||
global $config, $mod; |
global $board, $config; |
||||
if($config['mod']['server-side_confirm']) |
|
||||
return '<a onclick="if(confirm(\'' . htmlentities(addslashes($confirm)) . '\')) document.location=\'?/' . htmlentities(addslashes($href)) . '\';return false;" title="' . htmlentities($title) . '" href="?/confirm/' . $href . '">' . $text . '</a>'; |
return Element('post_reply.html', Array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index)); |
||||
else |
|
||||
return '<a onclick="return confirm(\'' . htmlentities(addslashes($confirm)) . '\')" title="' . htmlentities($title) . '" href="?/' . $href . '">' . $text . '</a>'; |
|
||||
} |
} |
||||
|
}; |
||||
class Post { |
|
||||
public function __construct($id, $thread, $subject, $email, $name, $trip, $capcode, $body, $time, $thumb, $thumbx, $thumby, $file, $filex, $filey, $filesize, $filename, $ip, $embed, $root=null, $mod=false) { |
class Thread { |
||||
global $config; |
public function __construct($id, $subject, $email, $name, $trip, $capcode, $body, $time, $thumb, $thumbx, $thumby, $file, $filex, $filey, $filesize, $filename, $ip, $sticky, $locked, $bumplocked, $embed, $root=null, $mod=false, $hr=true) { |
||||
if(!isset($root)) $root = &$config['root']; |
global $config; |
||||
|
if(!isset($root)) |
||||
|
$root = &$config['root']; |
||||
|
|
||||
|
$this->id = $id; |
||||
|
$this->subject = utf8tohtml($subject); |
||||
|
$this->email = $email; |
||||
|
$this->name = utf8tohtml($name); |
||||
|
$this->trip = $trip; |
||||
|
$this->capcode = $capcode; |
||||
|
$this->body = $body; |
||||
|
$this->time = $time; |
||||
|
$this->thumb = $thumb; |
||||
|
$this->thumbx = $thumbx; |
||||
|
$this->thumby = $thumby; |
||||
|
$this->file = $file; |
||||
|
$this->filex = $filex; |
||||
|
$this->filey = $filey; |
||||
|
$this->filesize = $filesize; |
||||
|
$this->filename = $filename; |
||||
|
$this->omitted = 0; |
||||
|
$this->omitted_images = 0; |
||||
|
$this->posts = Array(); |
||||
|
$this->ip = $ip; |
||||
|
$this->sticky = $sticky; |
||||
|
$this->locked = $locked; |
||||
|
$this->bumplocked = $bumplocked; |
||||
|
$this->embed = $embed; |
||||
|
$this->root = $root; |
||||
|
$this->mod = $mod; |
||||
|
$this->hr = $hr; |
||||
|
|
||||
|
if($this->mod) |
||||
|
// Fix internal links |
||||
|
// Very complicated regex |
||||
|
$this->body = preg_replace( |
||||
|
'/<a(([a-zA-Z]+="[^"]+")|[a-zA-Z]+=[a-zA-Z]+|\s)*href="' . preg_quote($config['root'], '/') . '(' . sprintf(preg_quote($config['board_path'], '/'), '\w+') . ')/', |
||||
|
'<a href="?/$3', |
||||
|
$this->body |
||||
|
); |
||||
|
} |
||||
|
public function link($pre = '') { |
||||
|
global $config, $board; |
||||
|
|
||||
|
return $this->root . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $this->id) . '#' . $pre . $this->id; |
||||
|
} |
||||
|
public function add(Post $post) { |
||||
|
$this->posts[] = $post; |
||||
|
} |
||||
|
public function postControls() { |
||||
|
global $board, $config; |
||||
|
|
||||
|
$built = ''; |
||||
|
if($this->mod) { |
||||
|
// Mod controls (on posts) |
||||
|
// Delete |
||||
|
if(hasPermission($config['mod']['delete'], $board['uri'], $this->mod)) |
||||
|
$built .= ' ' . confirmLink($config['mod']['link_delete'], 'Delete', 'Are you sure you want to delete this?', $board['uri'] . '/delete/' . $this->id); |
||||
|
|
||||
$this->id = $id; |
// Delete all posts by IP |
||||
$this->thread = $thread; |
if(hasPermission($config['mod']['deletebyip'], $board['uri'], $this->mod)) |
||||
$this->subject = utf8tohtml($subject); |
$built .= ' ' . confirmLink($config['mod']['link_deletebyip'], 'Delete all posts by IP', 'Are you sure you want to delete all posts by this IP address?', $board['uri'] . '/deletebyip/' . $this->id); |
||||
$this->email = $email; |
|
||||
$this->name = utf8tohtml($name); |
|
||||
$this->trip = $trip; |
|
||||
$this->capcode = $capcode; |
|
||||
$this->body = $body; |
|
||||
$this->time = $time; |
|
||||
$this->thumb = $thumb; |
|
||||
$this->thumbx = $thumbx; |
|
||||
$this->thumby = $thumby; |
|
||||
$this->file = $file; |
|
||||
$this->filex = $filex; |
|
||||
$this->filey = $filey; |
|
||||
$this->filesize = $filesize; |
|
||||
$this->filename = $filename; |
|
||||
$this->ip = $ip; |
|
||||
$this->embed = $embed; |
|
||||
$this->root = $root; |
|
||||
$this->mod = $mod; |
|
||||
|
|
||||
if($this->mod) |
// Delete all posts by IP (global) |
||||
// Fix internal links |
if(hasPermission($config['mod']['deletebyip_global'], $board['uri'], $this->mod)) |
||||
// Very complicated regex |
$built .= ' ' . confirmLink($config['mod']['link_deletebyip_global'], 'Delete all posts by IP across all boards', 'Are you sure you want to delete all posts by this IP address, across all boards?', $board['uri'] . '/deletebyip/' . $this->id . '/global'); |
||||
$this->body = preg_replace( |
|
||||
'/<a((([a-zA-Z]+="[^"]+")|[a-zA-Z]+=[a-zA-Z]+|\s)*)href="' . preg_quote($config['root'], '/') . '(' . sprintf(preg_quote($config['board_path'], '/'), '\w+') . ')/', |
|
||||
'<a $1href="?/$4', |
|
||||
$this->body |
|
||||
); |
|
||||
} |
|
||||
public function link($pre = '') { |
|
||||
global $config, $board; |
|
||||
|
|
||||
return $this->root . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $this->thread) . '#' . $pre . $this->id; |
// Ban |
||||
} |
if(hasPermission($config['mod']['ban'], $board['uri'], $this->mod)) |
||||
public function postControls() { |
$built .= ' <a title="Ban" href="?/' . $board['uri'] . '/ban/' . $this->id . '">' . $config['mod']['link_ban'] . '</a>'; |
||||
global $board, $config; |
|
||||
|
|
||||
$built = ''; |
// Ban & Delete |
||||
if($this->mod) { |
if(hasPermission($config['mod']['bandelete'], $board['uri'], $this->mod)) |
||||
// Mod controls (on posts) |
$built .= ' <a title="Ban & Delete" href="?/' . $board['uri'] . '/ban&delete/' . $this->id . '">' . $config['mod']['link_bandelete'] . '</a>'; |
||||
|
|
||||
// Delete |
|
||||
if(hasPermission($config['mod']['delete'], $board['uri'], $this->mod)) |
|
||||
$built .= ' ' . confirmLink($config['mod']['link_delete'], 'Delete', 'Are you sure you want to delete this?', $board['uri'] . '/delete/' . $this->id); |
|
||||
|
|
||||
// Delete all posts by IP |
|
||||
if(hasPermission($config['mod']['deletebyip'], $board['uri'], $this->mod)) |
|
||||
$built .= ' ' . confirmLink($config['mod']['link_deletebyip'], 'Delete all posts by IP', 'Are you sure you want to delete all posts by this IP address?', $board['uri'] . '/deletebyip/' . $this->id); |
|
||||
|
|
||||
// Delete all posts by IP (global) |
|
||||
if(hasPermission($config['mod']['deletebyip_global'], $board['uri'], $this->mod)) |
|
||||
$built .= ' ' . confirmLink($config['mod']['link_deletebyip_global'], 'Delete all posts by IP across all boards', 'Are you sure you want to delete all posts by this IP address, across all boards?', $board['uri'] . '/deletebyip/' . $this->id . '/global'); |
|
||||
|
|
||||
// Ban |
|
||||
if(hasPermission($config['mod']['ban'], $board['uri'], $this->mod)) |
|
||||
$built .= ' <a title="Ban" href="?/' . $board['uri'] . '/ban/' . $this->id . '">' . $config['mod']['link_ban'] . '</a>'; |
|
||||
|
|
||||
// Ban & Delete |
|
||||
if(hasPermission($config['mod']['bandelete'], $board['uri'], $this->mod)) |
|
||||
$built .= ' <a title="Ban & Delete" href="?/' . $board['uri'] . '/ban&delete/' . $this->id . '">' . $config['mod']['link_bandelete'] . '</a>'; |
|
||||
|
|
||||
// Delete file (keep post) |
|
||||
if(!empty($this->file) && hasPermission($config['mod']['deletefile'], $board['uri'], $this->mod)) |
|
||||
$built .= ' <a title="Remove file" href="?/' . $board['uri'] . '/deletefile/' . $this->id . '">' . $config['mod']['link_deletefile'] . '</a>'; |
|
||||
|
|
||||
// Edit post |
|
||||
if(hasPermission($config['mod']['editpost'], $board['uri'], $this->mod)) |
|
||||
$built .= ' <a title="Edit post" href="?/' . $board['uri'] . '/edit/' . $this->id . '">' . $config['mod']['link_editpost'] . '</a>'; |
|
||||
|
|
||||
if(!empty($built)) |
|
||||
$built = '<span class="controls">' . $built . '</span>'; |
|
||||
} |
|
||||
return $built; |
|
||||
} |
|
||||
|
|
||||
public function build($index=false) { |
|
||||
global $board, $config; |
|
||||
|
|
||||
return Element('post_reply.html', Array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index)); |
// Delete file (keep post) |
||||
} |
if(!empty($this->file) && $this->file != 'deleted' && hasPermission($config['mod']['deletefile'], $board['uri'], $this->mod)) |
||||
}; |
$built .= ' <a title="Remove file" href="?/' . $board['uri'] . '/deletefile/' . $this->id . '">' . $config['mod']['link_deletefile'] . '</a>'; |
||||
|
|
||||
class Thread { |
|
||||
public function __construct($id, $subject, $email, $name, $trip, $capcode, $body, $time, $thumb, $thumbx, $thumby, $file, $filex, $filey, $filesize, $filename, $ip, $sticky, $locked, $bumplocked, $embed, $root=null, $mod=false, $hr=true) { |
|
||||
global $config; |
|
||||
if(!isset($root)) $root = &$config['root']; |
|
||||
|
|
||||
$this->id = $id; |
// Sticky |
||||
$this->subject = utf8tohtml($subject); |
if(hasPermission($config['mod']['sticky'], $board['uri'], $this->mod)) |
||||
$this->email = $email; |
if($this->sticky) |
||||
$this->name = utf8tohtml($name); |
$built .= ' <a title="Make thread not sticky" href="?/' . $board['uri'] . '/unsticky/' . $this->id . '">' . $config['mod']['link_desticky'] . '</a>'; |
||||
$this->trip = $trip; |
else |
||||
$this->capcode = $capcode; |
$built .= ' <a title="Make thread sticky" href="?/' . $board['uri'] . '/sticky/' . $this->id . '">' . $config['mod']['link_sticky'] . '</a>'; |
||||
$this->body = $body; |
|
||||
$this->time = $time; |
|
||||
$this->thumb = $thumb; |
|
||||
$this->thumbx = $thumbx; |
|
||||
$this->thumby = $thumby; |
|
||||
$this->file = $file; |
|
||||
$this->filex = $filex; |
|
||||
$this->filey = $filey; |
|
||||
$this->filesize = $filesize; |
|
||||
$this->filename = $filename; |
|
||||
$this->omitted = 0; |
|
||||
$this->omitted_images = 0; |
|
||||
$this->posts = Array(); |
|
||||
$this->ip = $ip; |
|
||||
$this->sticky = $sticky; |
|
||||
$this->locked = $locked; |
|
||||
$this->bumplocked = $bumplocked; |
|
||||
$this->embed = $embed; |
|
||||
$this->root = $root; |
|
||||
$this->mod = $mod; |
|
||||
$this->hr = $hr; |
|
||||
|
|
||||
if($this->mod) |
if(hasPermission($config['mod']['bumplock'], $board['uri'], $this->mod)) |
||||
// Fix internal links |
if($this->bumplocked) |
||||
// Very complicated regex |
$built .= ' <a title="Allow thread to be bumped" href="?/' . $board['uri'] . '/bumpunlock/' . $this->id . '">' . $config['mod']['link_bumpunlock'] . '</a>'; |
||||
$this->body = preg_replace( |
else |
||||
'/<a(([a-zA-Z]+="[^"]+")|[a-zA-Z]+=[a-zA-Z]+|\s)*href="' . preg_quote($config['root'], '/') . '(' . sprintf(preg_quote($config['board_path'], '/'), '\w+') . ')/', |
$built .= ' <a title="Prevent thread from being bumped" href="?/' . $board['uri'] . '/bumplock/' . $this->id . '">' . $config['mod']['link_bumplock'] . '</a>'; |
||||
'<a href="?/$3', |
|
||||
$this->body |
|
||||
); |
|
||||
} |
|
||||
public function link($pre = '') { |
|
||||
global $config, $board; |
|
||||
|
|
||||
return $this->root . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $this->id) . '#' . $pre . $this->id; |
// Lock |
||||
} |
if(hasPermission($config['mod']['lock'], $board['uri'], $this->mod)) |
||||
public function add(Post $post) { |
if($this->locked) |
||||
$this->posts[] = $post; |
$built .= ' <a title="Unlock thread" href="?/' . $board['uri'] . '/unlock/' . $this->id . '">' . $config['mod']['link_unlock'] . '</a>'; |
||||
} |
else |
||||
public function postControls() { |
$built .= ' <a title="Lock thread" href="?/' . $board['uri'] . '/lock/' . $this->id . '">' . $config['mod']['link_lock'] . '</a>'; |
||||
global $board, $config; |
|
||||
|
|
||||
$built = ''; |
if(hasPermission($config['mod']['move'], $board['uri'], $this->mod)) |
||||
if($this->mod) { |
$built .= ' <a title="Move thread to another board" href="?/' . $board['uri'] . '/move/' . $this->id . '">' . $config['mod']['link_move'] . '</a>'; |
||||
// Mod controls (on posts) |
|
||||
// Delete |
|
||||
if(hasPermission($config['mod']['delete'], $board['uri'], $this->mod)) |
|
||||
$built .= ' ' . confirmLink($config['mod']['link_delete'], 'Delete', 'Are you sure you want to delete this?', $board['uri'] . '/delete/' . $this->id); |
|
||||
|
|
||||
// Delete all posts by IP |
|
||||
if(hasPermission($config['mod']['deletebyip'], $board['uri'], $this->mod)) |
|
||||
$built .= ' ' . confirmLink($config['mod']['link_deletebyip'], 'Delete all posts by IP', 'Are you sure you want to delete all posts by this IP address?', $board['uri'] . '/deletebyip/' . $this->id); |
|
||||
|
|
||||
// Delete all posts by IP (global) |
|
||||
if(hasPermission($config['mod']['deletebyip_global'], $board['uri'], $this->mod)) |
|
||||
$built .= ' ' . confirmLink($config['mod']['link_deletebyip_global'], 'Delete all posts by IP across all boards', 'Are you sure you want to delete all posts by this IP address, across all boards?', $board['uri'] . '/deletebyip/' . $this->id . '/global'); |
|
||||
|
|
||||
// Ban |
|
||||
if(hasPermission($config['mod']['ban'], $board['uri'], $this->mod)) |
|
||||
$built .= ' <a title="Ban" href="?/' . $board['uri'] . '/ban/' . $this->id . '">' . $config['mod']['link_ban'] . '</a>'; |
|
||||
|
|
||||
// Ban & Delete |
|
||||
if(hasPermission($config['mod']['bandelete'], $board['uri'], $this->mod)) |
|
||||
$built .= ' <a title="Ban & Delete" href="?/' . $board['uri'] . '/ban&delete/' . $this->id . '">' . $config['mod']['link_bandelete'] . '</a>'; |
|
||||
|
|
||||
// Delete file (keep post) |
|
||||
if(!empty($this->file) && $this->file != 'deleted' && hasPermission($config['mod']['deletefile'], $board['uri'], $this->mod)) |
|
||||
$built .= ' <a title="Remove file" href="?/' . $board['uri'] . '/deletefile/' . $this->id . '">' . $config['mod']['link_deletefile'] . '</a>'; |
|
||||
|
|
||||
// Sticky |
|
||||
if(hasPermission($config['mod']['sticky'], $board['uri'], $this->mod)) |
|
||||
if($this->sticky) |
|
||||
$built .= ' <a title="Make thread not sticky" href="?/' . $board['uri'] . '/unsticky/' . $this->id . '">' . $config['mod']['link_desticky'] . '</a>'; |
|
||||
else |
|
||||
$built .= ' <a title="Make thread sticky" href="?/' . $board['uri'] . '/sticky/' . $this->id . '">' . $config['mod']['link_sticky'] . '</a>'; |
|
||||
|
|
||||
if(hasPermission($config['mod']['bumplock'], $board['uri'], $this->mod)) |
|
||||
if($this->bumplocked) |
|
||||
$built .= ' <a title="Allow thread to be bumped" href="?/' . $board['uri'] . '/bumpunlock/' . $this->id . '">' . $config['mod']['link_bumpunlock'] . '</a>'; |
|
||||
else |
|
||||
$built .= ' <a title="Prevent thread from being bumped" href="?/' . $board['uri'] . '/bumplock/' . $this->id . '">' . $config['mod']['link_bumplock'] . '</a>'; |
|
||||
|
|
||||
// Lock |
|
||||
if(hasPermission($config['mod']['lock'], $board['uri'], $this->mod)) |
|
||||
if($this->locked) |
|
||||
$built .= ' <a title="Unlock thread" href="?/' . $board['uri'] . '/unlock/' . $this->id . '">' . $config['mod']['link_unlock'] . '</a>'; |
|
||||
else |
|
||||
$built .= ' <a title="Lock thread" href="?/' . $board['uri'] . '/lock/' . $this->id . '">' . $config['mod']['link_lock'] . '</a>'; |
|
||||
|
|
||||
if(hasPermission($config['mod']['move'], $board['uri'], $this->mod)) |
|
||||
$built .= ' <a title="Move thread to another board" href="?/' . $board['uri'] . '/move/' . $this->id . '">' . $config['mod']['link_move'] . '</a>'; |
|
||||
|
|
||||
// Edit post |
|
||||
if(hasPermission($config['mod']['editpost'], $board['uri'], $this->mod)) |
|
||||
$built .= ' <a title="Edit post" href="?/' . $board['uri'] . '/edit/' . $this->id . '">' . $config['mod']['link_editpost'] . '</a>'; |
|
||||
|
|
||||
if(!empty($built)) |
|
||||
$built = '<span class="controls op">' . $built . '</span>'; |
|
||||
} |
|
||||
return $built; |
|
||||
} |
|
||||
|
|
||||
public function ratio() { |
|
||||
return fraction($this->filex, $this->filey, ':'); |
|
||||
} |
|
||||
|
|
||||
public function build($index=false) { |
|
||||
global $board, $config, $debug; |
|
||||
|
|
||||
$built = Element('post_thread.html', Array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index)); |
// Edit post |
||||
|
if(hasPermission($config['mod']['editpost'], $board['uri'], $this->mod)) |
||||
|
$built .= ' <a title="Edit post" href="?/' . $board['uri'] . '/edit/' . $this->id . '">' . $config['mod']['link_editpost'] . '</a>'; |
||||
|
|
||||
if(!$this->mod && $index && $config['cache']['enabled']) { |
if(!empty($built)) |
||||
cache::set($this->cache_key($index), $built); |
$built = '<span class="controls op">' . $built . '</span>'; |
||||
} |
|
||||
|
|
||||
return $built; |
|
||||
} |
} |
||||
function cache_key($index) { |
return $built; |
||||
global $board; |
} |
||||
|
|
||||
return 'thread_' . ($index ? 'index_' : '') . $board['uri'] . '_' . $this->id; |
public function ratio() { |
||||
|
return fraction($this->filex, $this->filey, ':'); |
||||
|
} |
||||
|
|
||||
|
public function build($index=false) { |
||||
|
global $board, $config, $debug; |
||||
|
|
||||
|
$built = Element('post_thread.html', Array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index)); |
||||
|
|
||||
|
if(!$this->mod && $index && $config['cache']['enabled']) { |
||||
|
cache::set($this->cache_key($index), $built); |
||||
} |
} |
||||
}; |
|
||||
?> |
return $built; |
||||
|
} |
||||
|
function cache_key($index) { |
||||
|
global $board; |
||||
|
|
||||
|
return 'thread_' . ($index ? 'index_' : '') . $board['uri'] . '_' . $this->id; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
File diff suppressed because it is too large
@ -1,488 +1,491 @@ |
|||||
<?php |
<?php |
||||
if($_SERVER['SCRIPT_FILENAME'] == str_replace('\\', '/', __FILE__)) { |
|
||||
// You cannot request this file directly. |
|
||||
header('Location: ../', true, 302); |
|
||||
exit; |
|
||||
} |
|
||||
|
|
||||
class Image { |
/* |
||||
public $src, $format, $image, $size; |
* Copyright (c) 2010-2012 Tinyboard Development Group |
||||
public function __construct($src, $format = false) { |
*/ |
||||
global $config; |
|
||||
|
if(realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) { |
||||
$this->src = $src; |
// You cannot request this file directly. |
||||
$this->format = $format; |
exit; |
||||
|
} |
||||
if($config['thumb_method'] == 'imagick') { |
|
||||
$classname = 'ImageImagick'; |
class Image { |
||||
} elseif($config['thumb_method'] == 'convert') { |
public $src, $format, $image, $size; |
||||
$classname = 'ImageConvert'; |
public function __construct($src, $format = false) { |
||||
} else { |
global $config; |
||||
$classname = 'Image' . strtoupper($this->format); |
|
||||
if(!class_exists($classname)) { |
|
||||
error('Unsupported file format: ' . $this->format); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
$this->image = new $classname($this); |
|
||||
if(!$this->image->valid()) { |
|
||||
$this->delete(); |
|
||||
error($config['error']['invalidimg']); |
|
||||
} |
|
||||
|
|
||||
$this->size = (object)Array('width' => $this->image->_width(), 'height' => $this->image->_height()); |
|
||||
if($this->size->width < 1 || $this->size->height < 1) { |
|
||||
$this->delete(); |
|
||||
error($config['error']['invalidimg']); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function resize($extension, $max_width, $max_height) { |
$this->src = $src; |
||||
global $config; |
$this->format = $format; |
||||
|
|
||||
if($config['thumb_method'] == 'imagick') { |
if($config['thumb_method'] == 'imagick') { |
||||
$classname = 'ImageImagick'; |
$classname = 'ImageImagick'; |
||||
} elseif($config['thumb_method'] == 'convert') { |
} elseif($config['thumb_method'] == 'convert') { |
||||
$classname = 'ImageConvert'; |
$classname = 'ImageConvert'; |
||||
} else { |
} else { |
||||
$classname = 'Image' . strtoupper($extension); |
$classname = 'Image' . strtoupper($this->format); |
||||
if(!class_exists($classname)) { |
if(!class_exists($classname)) { |
||||
error('Unsupported file format: ' . $extension); |
error('Unsupported file format: ' . $this->format); |
||||
} |
|
||||
} |
|
||||
|
|
||||
$thumb = new $classname(false); |
|
||||
$thumb->src = $this->src; |
|
||||
$thumb->original_width = $this->size->width; |
|
||||
$thumb->original_height = $this->size->height; |
|
||||
|
|
||||
$x_ratio = $max_width / $this->size->width; |
|
||||
$y_ratio = $max_height / $this->size->height; |
|
||||
|
|
||||
if(($this->size->width <= $max_width) && ($this->size->height <= $max_height)) { |
|
||||
$width = $this->size->width; |
|
||||
$height = $this->size->height; |
|
||||
} elseif (($x_ratio * $this->size->height) < $max_height) { |
|
||||
$height = ceil($x_ratio * $this->size->height); |
|
||||
$width = $max_width; |
|
||||
} else { |
|
||||
$width = ceil($y_ratio * $this->size->width); |
|
||||
$height = $max_height; |
|
||||
} |
} |
||||
|
|
||||
$thumb->_resize($this->image->image, $width, $height); |
|
||||
return $thumb; |
|
||||
} |
} |
||||
|
|
||||
public function to($dst) { |
$this->image = new $classname($this); |
||||
$this->image->to($dst); |
if(!$this->image->valid()) { |
||||
|
$this->delete(); |
||||
|
error($config['error']['invalidimg']); |
||||
} |
} |
||||
|
|
||||
public function delete() { |
$this->size = (object)Array('width' => $this->image->_width(), 'height' => $this->image->_height()); |
||||
file_unlink($this->src); |
if($this->size->width < 1 || $this->size->height < 1) { |
||||
} |
$this->delete(); |
||||
public function destroy() { |
error($config['error']['invalidimg']); |
||||
$this->image->_destroy(); |
|
||||
} |
} |
||||
} |
} |
||||
|
|
||||
class ImageGD { |
public function resize($extension, $max_width, $max_height) { |
||||
public function GD_create() { |
global $config; |
||||
$this->image = imagecreatetruecolor($this->width, $this->height); |
|
||||
} |
if($config['thumb_method'] == 'imagick') { |
||||
public function GD_copyresampled() { |
$classname = 'ImageImagick'; |
||||
imagecopyresampled($this->image, $this->original, 0, 0, 0, 0, $this->width, $this->height, $this->original_width, $this->original_height); |
} elseif($config['thumb_method'] == 'convert') { |
||||
|
$classname = 'ImageConvert'; |
||||
|
} else { |
||||
|
$classname = 'Image' . strtoupper($extension); |
||||
|
if(!class_exists($classname)) { |
||||
|
error('Unsupported file format: ' . $extension); |
||||
|
} |
||||
} |
} |
||||
public function GD_resize() { |
|
||||
$this->GD_create(); |
$thumb = new $classname(false); |
||||
$this->GD_copyresampled(); |
$thumb->src = $this->src; |
||||
|
$thumb->original_width = $this->size->width; |
||||
|
$thumb->original_height = $this->size->height; |
||||
|
|
||||
|
$x_ratio = $max_width / $this->size->width; |
||||
|
$y_ratio = $max_height / $this->size->height; |
||||
|
|
||||
|
if(($this->size->width <= $max_width) && ($this->size->height <= $max_height)) { |
||||
|
$width = $this->size->width; |
||||
|
$height = $this->size->height; |
||||
|
} elseif (($x_ratio * $this->size->height) < $max_height) { |
||||
|
$height = ceil($x_ratio * $this->size->height); |
||||
|
$width = $max_width; |
||||
|
} else { |
||||
|
$width = ceil($y_ratio * $this->size->width); |
||||
|
$height = $max_height; |
||||
} |
} |
||||
|
|
||||
|
$thumb->_resize($this->image->image, $width, $height); |
||||
|
return $thumb; |
||||
} |
} |
||||
|
|
||||
class ImageBase extends ImageGD { |
public function to($dst) { |
||||
public $image, $src, $original, $original_width, $original_height, $width, $height; |
$this->image->to($dst); |
||||
public function valid() { |
} |
||||
return (bool)$this->image; |
|
||||
} |
public function delete() { |
||||
|
file_unlink($this->src); |
||||
|
} |
||||
|
public function destroy() { |
||||
|
$this->image->_destroy(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class ImageGD { |
||||
|
public function GD_create() { |
||||
|
$this->image = imagecreatetruecolor($this->width, $this->height); |
||||
|
} |
||||
|
public function GD_copyresampled() { |
||||
|
imagecopyresampled($this->image, $this->original, 0, 0, 0, 0, $this->width, $this->height, $this->original_width, $this->original_height); |
||||
|
} |
||||
|
public function GD_resize() { |
||||
|
$this->GD_create(); |
||||
|
$this->GD_copyresampled(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class ImageBase extends ImageGD { |
||||
|
public $image, $src, $original, $original_width, $original_height, $width, $height; |
||||
|
public function valid() { |
||||
|
return (bool)$this->image; |
||||
|
} |
||||
|
|
||||
|
public function __construct($img) { |
||||
|
if(method_exists($this, 'init')) |
||||
|
$this->init(); |
||||
|
|
||||
public function __construct($img) { |
if($img !== false) { |
||||
if(method_exists($this, 'init')) |
$this->src = $img->src; |
||||
$this->init(); |
$this->from(); |
||||
|
|
||||
if($img !== false) { |
|
||||
$this->src = $img->src; |
|
||||
$this->from(); |
|
||||
} |
|
||||
} |
} |
||||
|
} |
||||
|
|
||||
|
public function _width() { |
||||
|
if(method_exists($this, 'width')) |
||||
|
return $this->width(); |
||||
|
// use default GD functions |
||||
|
return imagesx($this->image); |
||||
|
} |
||||
|
public function _height() { |
||||
|
if(method_exists($this, 'height')) |
||||
|
return $this->height(); |
||||
|
// use default GD functions |
||||
|
return imagesy($this->image); |
||||
|
} |
||||
|
public function _destroy() { |
||||
|
if(method_exists($this, 'destroy')) |
||||
|
return $this->destroy(); |
||||
|
// use default GD functions |
||||
|
return imagedestroy($this->image); |
||||
|
} |
||||
|
public function _resize($original, $width, $height) { |
||||
|
$this->original = &$original; |
||||
|
$this->width = $width; |
||||
|
$this->height = $height; |
||||
|
|
||||
public function _width() { |
if(method_exists($this, 'resize')) |
||||
if(method_exists($this, 'width')) |
$this->resize(); |
||||
return $this->width(); |
else |
||||
// use default GD functions |
|
||||
return imagesx($this->image); |
|
||||
} |
|
||||
public function _height() { |
|
||||
if(method_exists($this, 'height')) |
|
||||
return $this->height(); |
|
||||
// use default GD functions |
|
||||
return imagesy($this->image); |
|
||||
} |
|
||||
public function _destroy() { |
|
||||
if(method_exists($this, 'destroy')) |
|
||||
return $this->destroy(); |
|
||||
// use default GD functions |
// use default GD functions |
||||
return imagedestroy($this->image); |
$this->GD_resize(); |
||||
} |
} |
||||
public function _resize($original, $width, $height) { |
} |
||||
$this->original = &$original; |
|
||||
$this->width = $width; |
class ImageImagick extends ImageBase { |
||||
$this->height = $height; |
public function init() { |
||||
|
$this->image = new Imagick(); |
||||
if(method_exists($this, 'resize')) |
$this->image->setBackgroundColor(new ImagickPixel('transparent')); |
||||
$this->resize(); |
} |
||||
else |
public function from() { |
||||
// use default GD functions |
try { |
||||
$this->GD_resize(); |
$this->image->readImage($this->src); |
||||
|
} catch(ImagickException $e) { |
||||
|
// invalid image |
||||
|
$this->image = false; |
||||
} |
} |
||||
} |
} |
||||
|
public function to($src) { |
||||
class ImageImagick extends ImageBase { |
if(preg_match('/\.gif$/i', $src)) |
||||
public function init() { |
$this->image->writeImages($src, true); |
||||
|
else |
||||
|
$this->image->writeImage($src); |
||||
|
} |
||||
|
public function width() { |
||||
|
return $this->image->getImageWidth(); |
||||
|
} |
||||
|
public function height() { |
||||
|
return $this->image->getImageHeight(); |
||||
|
} |
||||
|
public function destroy() { |
||||
|
return $this->image->destroy(); |
||||
|
} |
||||
|
public function resize() { |
||||
|
global $config; |
||||
|
|
||||
|
if(preg_match('/\.gif$/i', $this->src) && $config['thumb_ext'] == 'gif') { |
||||
$this->image = new Imagick(); |
$this->image = new Imagick(); |
||||
$this->image->setBackgroundColor(new ImagickPixel('transparent')); |
$this->image->setFormat('gif'); |
||||
} |
|
||||
public function from() { |
|
||||
try { |
|
||||
$this->image->readImage($this->src); |
|
||||
} catch(ImagickException $e) { |
|
||||
// invalid image |
|
||||
$this->image = false; |
|
||||
} |
|
||||
} |
|
||||
public function to($src) { |
|
||||
if(preg_match('/\.gif$/i', $src)) |
|
||||
$this->image->writeImages($src, true); |
|
||||
else |
|
||||
$this->image->writeImage($src); |
|
||||
} |
|
||||
public function width() { |
|
||||
return $this->image->getImageWidth(); |
|
||||
} |
|
||||
public function height() { |
|
||||
return $this->image->getImageHeight(); |
|
||||
} |
|
||||
public function destroy() { |
|
||||
return $this->image->destroy(); |
|
||||
} |
|
||||
public function resize() { |
|
||||
global $config; |
|
||||
|
|
||||
if(preg_match('/\.gif$/i', $this->src) && $config['thumb_ext'] == 'gif') { |
$keep_frames = Array(); |
||||
$this->image = new Imagick(); |
for($i = 0; $i < $this->original->getNumberImages(); $i += floor($this->original->getNumberImages() / $config['thumb_keep_animation_frames'])) |
||||
$this->image->setFormat('gif'); |
$keep_frames[] = $i; |
||||
|
|
||||
$keep_frames = Array(); |
$i = 0; |
||||
for($i = 0; $i < $this->original->getNumberImages(); $i += floor($this->original->getNumberImages() / $config['thumb_keep_animation_frames'])) |
$delay = 0; |
||||
$keep_frames[] = $i; |
foreach($this->original as $frame) { |
||||
|
$delay += $frame->getImageDelay(); |
||||
|
|
||||
$i = 0; |
//if($i < $config['thumb_keep_animation_frames']) { |
||||
$delay = 0; |
if(in_array($i, $keep_frames)) { |
||||
foreach($this->original as $frame) { |
// $frame->scaleImage($this->width, $this->height, false); |
||||
$delay += $frame->getImageDelay(); |
$frame->sampleImage($this->width, $this->height); |
||||
|
$frame->setImagePage($this->width, $this->height, 0, 0); |
||||
|
$frame->setImageDelay($delay); |
||||
|
$delay = 0; |
||||
|
|
||||
//if($i < $config['thumb_keep_animation_frames']) { |
$this->image->addImage($frame->getImage()); |
||||
if(in_array($i, $keep_frames)) { |
} |
||||
// $frame->scaleImage($this->width, $this->height, false); |
$i++; |
||||
$frame->sampleImage($this->width, $this->height); |
} |
||||
$frame->setImagePage($this->width, $this->height, 0, 0); |
} else { |
||||
$frame->setImageDelay($delay); |
$this->image = clone $this->original; |
||||
$delay = 0; |
$this->image->scaleImage($this->width, $this->height, false); |
||||
|
|
||||
$this->image->addImage($frame->getImage()); |
|
||||
} |
|
||||
$i++; |
|
||||
} |
|
||||
} else { |
|
||||
$this->image = clone $this->original; |
|
||||
$this->image->scaleImage($this->width, $this->height, false); |
|
||||
} |
|
||||
} |
} |
||||
} |
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
class ImageConvert extends ImageBase { |
||||
|
public $width, $height, $temp; |
||||
|
|
||||
|
public function init() { |
||||
class ImageConvert extends ImageBase { |
global $config; |
||||
public $width, $height, $temp; |
|
||||
|
|
||||
public function init() { |
$this->temp = false; |
||||
global $config; |
} |
||||
|
public function from() { |
||||
$this->temp = false; |
$size = trim(shell_exec('identify -format "%w %h" ' . escapeshellarg($this->src . '[0]'))); |
||||
} |
if(preg_match('/^(\d+) (\d+)$/', $size, $m)) { |
||||
public function from() { |
$this->width = $m[1]; |
||||
$size = trim(shell_exec('identify -format "%w %h" ' . escapeshellarg($this->src . '[0]'))); |
$this->height = $m[2]; |
||||
if(preg_match('/^(\d+) (\d+)$/', $size, $m)) { |
|
||||
$this->width = $m[1]; |
|
||||
$this->height = $m[2]; |
|
||||
|
|
||||
$this->image = true; |
|
||||
} else { |
|
||||
// mark as invalid |
|
||||
$this->image = false; |
|
||||
} |
|
||||
} |
|
||||
public function to($src) { |
|
||||
if(!$this->temp) { |
|
||||
// $config['redraw_image'] |
|
||||
shell_exec('convert ' . escapeshellarg($this->src) . ' ' . escapeshellarg($src)); |
|
||||
} else { |
|
||||
rename($this->temp, $src); |
|
||||
chmod($src, 0664); |
|
||||
} |
|
||||
} |
|
||||
public function width() { |
|
||||
return $this->width; |
|
||||
} |
|
||||
public function height() { |
|
||||
return $this->height; |
|
||||
} |
|
||||
public function destroy() { |
|
||||
@unlink($this->temp); |
|
||||
$this->temp = false; |
|
||||
} |
|
||||
public function resize() { |
|
||||
global $config; |
|
||||
|
|
||||
if($this->temp) { |
|
||||
// remove old |
|
||||
$this->destroy(); |
|
||||
} |
|
||||
|
|
||||
$this->temp = tempnam($config['tmp'], 'imagick'); |
|
||||
|
|
||||
$quality = $config['thumb_quality'] * 10; |
|
||||
|
|
||||
if(shell_exec("convert -flatten -filter Point -scale {$this->width}x{$this->height} +antialias -quality {$quality} " . escapeshellarg($this->src . '[0]') . " " . escapeshellarg($this->temp)) || !file_exists($this->temp)) |
$this->image = true; |
||||
error('Failed to resize image!'); |
} else { |
||||
|
// mark as invalid |
||||
|
$this->image = false; |
||||
} |
} |
||||
} |
} |
||||
|
public function to($src) { |
||||
class ImagePNG extends ImageBase { |
if(!$this->temp) { |
||||
public function from() { |
// $config['redraw_image'] |
||||
$this->image = @imagecreatefrompng($this->src); |
shell_exec('convert ' . escapeshellarg($this->src) . ' ' . escapeshellarg($src)); |
||||
} |
} else { |
||||
public function to($src) { |
rename($this->temp, $src); |
||||
global $config; |
chmod($src, 0664); |
||||
imagepng($this->image, $src, $config['thumb_quality']); |
|
||||
} |
|
||||
public function resize() { |
|
||||
$this->GD_create(); |
|
||||
imagecolortransparent($this->image, imagecolorallocatealpha($this->image, 0, 0, 0, 0)); |
|
||||
imagesavealpha($this->image, true); |
|
||||
imagealphablending($this->image, false); |
|
||||
$this->GD_copyresampled(); |
|
||||
} |
} |
||||
} |
} |
||||
|
public function width() { |
||||
class ImageGIF extends ImageBase { |
return $this->width; |
||||
public function from() { |
|
||||
$this->image = @imagecreatefromgif($this->src); |
|
||||
} |
|
||||
public function to($src) { |
|
||||
imagegif($this->image, $src); |
|
||||
} |
|
||||
public function resize() { |
|
||||
$this->GD_create(); |
|
||||
imagecolortransparent($this->image, imagecolorallocatealpha($this->image, 0, 0, 0, 0)); |
|
||||
imagesavealpha($this->image, true); |
|
||||
$this->GD_copyresampled(); |
|
||||
} |
|
||||
} |
} |
||||
|
public function height() { |
||||
class ImageJPG extends ImageBase { |
return $this->height; |
||||
public function from() { |
|
||||
$this->image = @imagecreatefromjpeg($this->src); |
|
||||
} |
|
||||
public function to($src) { |
|
||||
imagejpeg($this->image, $src); |
|
||||
} |
|
||||
} |
} |
||||
class ImageJPEG extends ImageJPG { |
public function destroy() { |
||||
|
@unlink($this->temp); |
||||
|
$this->temp = false; |
||||
} |
} |
||||
|
public function resize() { |
||||
class ImageBMP extends ImageBase { |
global $config; |
||||
public function from() { |
|
||||
$this->image = @imagecreatefrombmp($this->src); |
if($this->temp) { |
||||
} |
// remove old |
||||
public function to($src) { |
$this->destroy(); |
||||
imagebmp($this->image, $src); |
|
||||
} |
} |
||||
|
|
||||
|
$this->temp = tempnam($config['tmp'], 'imagick'); |
||||
|
|
||||
|
$quality = $config['thumb_quality'] * 10; |
||||
|
|
||||
|
if(shell_exec("convert -flatten -filter Point -scale {$this->width}x{$this->height} +antialias -quality {$quality} " . escapeshellarg($this->src . '[0]') . " " . escapeshellarg($this->temp)) || !file_exists($this->temp)) |
||||
|
error('Failed to resize image!'); |
||||
} |
} |
||||
|
} |
||||
|
|
||||
/*********************************************/ |
|
||||
/* Fonction: imagecreatefrombmp */ |
|
||||
/* Author: DHKold */ |
|
||||
/* Contact: [email protected] */ |
|
||||
/* Date: The 15th of June 2005 */ |
|
||||
/* Version: 2.0B */ |
|
||||
/*********************************************/ |
|
||||
|
|
||||
function imagecreatefrombmp($filename) { |
|
||||
if (! $f1 = fopen($filename,"rb")) return FALSE; |
|
||||
$FILE = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1,14)); |
|
||||
if ($FILE['file_type'] != 19778) return FALSE; |
|
||||
$BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'. |
|
||||
'/Vcompression/Vsize_bitmap/Vhoriz_resolution'. |
|
||||
'/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1,40)); |
|
||||
$BMP['colors'] = pow(2,$BMP['bits_per_pixel']); |
|
||||
if ($BMP['size_bitmap'] == 0) $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset']; |
|
||||
$BMP['bytes_per_pixel'] = $BMP['bits_per_pixel']/8; |
|
||||
$BMP['bytes_per_pixel2'] = ceil($BMP['bytes_per_pixel']); |
|
||||
$BMP['decal'] = ($BMP['width']*$BMP['bytes_per_pixel']/4); |
|
||||
$BMP['decal'] -= floor($BMP['width']*$BMP['bytes_per_pixel']/4); |
|
||||
$BMP['decal'] = 4-(4*$BMP['decal']); |
|
||||
if ($BMP['decal'] == 4) $BMP['decal'] = 0; |
|
||||
|
|
||||
$PALETTE = array(); |
class ImagePNG extends ImageBase { |
||||
if ($BMP['colors'] < 16777216) |
public function from() { |
||||
{ |
$this->image = @imagecreatefrompng($this->src); |
||||
$PALETTE = unpack('V'.$BMP['colors'], fread($f1,$BMP['colors']*4)); |
} |
||||
} |
public function to($src) { |
||||
|
global $config; |
||||
|
imagepng($this->image, $src, $config['thumb_quality']); |
||||
|
} |
||||
|
public function resize() { |
||||
|
$this->GD_create(); |
||||
|
imagecolortransparent($this->image, imagecolorallocatealpha($this->image, 0, 0, 0, 0)); |
||||
|
imagesavealpha($this->image, true); |
||||
|
imagealphablending($this->image, false); |
||||
|
$this->GD_copyresampled(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
$IMG = fread($f1,$BMP['size_bitmap']); |
class ImageGIF extends ImageBase { |
||||
$VIDE = chr(0); |
public function from() { |
||||
|
$this->image = @imagecreatefromgif($this->src); |
||||
|
} |
||||
|
public function to($src) { |
||||
|
imagegif($this->image, $src); |
||||
|
} |
||||
|
public function resize() { |
||||
|
$this->GD_create(); |
||||
|
imagecolortransparent($this->image, imagecolorallocatealpha($this->image, 0, 0, 0, 0)); |
||||
|
imagesavealpha($this->image, true); |
||||
|
$this->GD_copyresampled(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
$res = imagecreatetruecolor($BMP['width'],$BMP['height']); |
class ImageJPG extends ImageBase { |
||||
$P = 0; |
public function from() { |
||||
$Y = $BMP['height']-1; |
$this->image = @imagecreatefromjpeg($this->src); |
||||
while ($Y >= 0) |
} |
||||
{ |
public function to($src) { |
||||
$X=0; |
imagejpeg($this->image, $src); |
||||
while ($X < $BMP['width']) |
} |
||||
{ |
} |
||||
if ($BMP['bits_per_pixel'] == 24) |
class ImageJPEG extends ImageJPG { |
||||
$COLOR = unpack("V",substr($IMG,$P,3).$VIDE); |
} |
||||
elseif ($BMP['bits_per_pixel'] == 16) |
|
||||
{ |
|
||||
$COLOR = unpack("n",substr($IMG,$P,2)); |
|
||||
$COLOR[1] = $PALETTE[$COLOR[1]+1]; |
|
||||
} |
|
||||
elseif ($BMP['bits_per_pixel'] == 8) |
|
||||
{ |
|
||||
$COLOR = unpack("n",$VIDE.substr($IMG,$P,1)); |
|
||||
$COLOR[1] = $PALETTE[$COLOR[1]+1]; |
|
||||
} |
|
||||
elseif ($BMP['bits_per_pixel'] == 4) |
|
||||
{ |
|
||||
$COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1)); |
|
||||
if (($P*2)%2 == 0) $COLOR[1] = ($COLOR[1] >> 4) ; else $COLOR[1] = ($COLOR[1] & 0x0F); |
|
||||
$COLOR[1] = $PALETTE[$COLOR[1]+1]; |
|
||||
} |
|
||||
elseif ($BMP['bits_per_pixel'] == 1) |
|
||||
{ |
|
||||
$COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1)); |
|
||||
if (($P*8)%8 == 0) $COLOR[1] = $COLOR[1] >>7; |
|
||||
elseif (($P*8)%8 == 1) $COLOR[1] = ($COLOR[1] & 0x40)>>6; |
|
||||
elseif (($P*8)%8 == 2) $COLOR[1] = ($COLOR[1] & 0x20)>>5; |
|
||||
elseif (($P*8)%8 == 3) $COLOR[1] = ($COLOR[1] & 0x10)>>4; |
|
||||
elseif (($P*8)%8 == 4) $COLOR[1] = ($COLOR[1] & 0x8)>>3; |
|
||||
elseif (($P*8)%8 == 5) $COLOR[1] = ($COLOR[1] & 0x4)>>2; |
|
||||
elseif (($P*8)%8 == 6) $COLOR[1] = ($COLOR[1] & 0x2)>>1; |
|
||||
elseif (($P*8)%8 == 7) $COLOR[1] = ($COLOR[1] & 0x1); |
|
||||
$COLOR[1] = $PALETTE[$COLOR[1]+1]; |
|
||||
} |
|
||||
else |
|
||||
return FALSE; |
|
||||
imagesetpixel($res,$X,$Y,$COLOR[1]); |
|
||||
$X++; |
|
||||
$P += $BMP['bytes_per_pixel']; |
|
||||
} |
|
||||
$Y--; |
|
||||
$P+=$BMP['decal']; |
|
||||
} |
|
||||
fclose($f1); |
|
||||
|
|
||||
return $res; |
class ImageBMP extends ImageBase { |
||||
|
public function from() { |
||||
|
$this->image = @imagecreatefrombmp($this->src); |
||||
} |
} |
||||
|
public function to($src) { |
||||
function imagebmp(&$img, $filename='') { |
imagebmp($this->image, $src); |
||||
$widthOrig = imagesx($img); |
} |
||||
$widthFloor = ((floor($widthOrig/16))*16); |
} |
||||
$widthCeil = ((ceil($widthOrig/16))*16); |
|
||||
$height = imagesy($img); |
|
||||
|
|
||||
$size = ($widthCeil*$height*3)+54; |
|
||||
|
|
||||
// Bitmap File Header |
/*********************************************/ |
||||
$result = 'BM'; // header (2b) |
/* Fonction: imagecreatefrombmp */ |
||||
$result .= int_to_dword($size); // size of file (4b) |
/* Author: DHKold */ |
||||
$result .= int_to_dword(0); // reserved (4b) |
/* Contact: [email protected] */ |
||||
$result .= int_to_dword(54); // byte location in the file which is first byte of IMAGE (4b) |
/* Date: The 15th of June 2005 */ |
||||
// Bitmap Info Header |
/* Version: 2.0B */ |
||||
$result .= int_to_dword(40); // Size of BITMAPINFOHEADER (4b) |
/*********************************************/ |
||||
$result .= int_to_dword($widthCeil); // width of bitmap (4b) |
|
||||
$result .= int_to_dword($height); // height of bitmap (4b) |
|
||||
$result .= int_to_word(1); // biPlanes = 1 (2b) |
|
||||
$result .= int_to_word(24); // biBitCount = {1 (mono) or 4 (16 clr ) or 8 (256 clr) or 24 (16 Mil)} (2b |
|
||||
$result .= int_to_dword(0); // RLE COMPRESSION (4b) |
|
||||
$result .= int_to_dword(0); // width x height (4b) |
|
||||
$result .= int_to_dword(0); // biXPelsPerMeter (4b) |
|
||||
$result .= int_to_dword(0); // biYPelsPerMeter (4b) |
|
||||
$result .= int_to_dword(0); // Number of palettes used (4b) |
|
||||
$result .= int_to_dword(0); // Number of important colour (4b) |
|
||||
|
|
||||
// is faster than chr() |
function imagecreatefrombmp($filename) { |
||||
$arrChr = array(); |
if (! $f1 = fopen($filename,"rb")) return FALSE; |
||||
for($i=0; $i<256; $i++){ |
$FILE = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1,14)); |
||||
$arrChr[$i] = chr($i); |
if ($FILE['file_type'] != 19778) return FALSE; |
||||
} |
$BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'. |
||||
|
'/Vcompression/Vsize_bitmap/Vhoriz_resolution'. |
||||
|
'/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1,40)); |
||||
|
$BMP['colors'] = pow(2,$BMP['bits_per_pixel']); |
||||
|
if ($BMP['size_bitmap'] == 0) $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset']; |
||||
|
$BMP['bytes_per_pixel'] = $BMP['bits_per_pixel']/8; |
||||
|
$BMP['bytes_per_pixel2'] = ceil($BMP['bytes_per_pixel']); |
||||
|
$BMP['decal'] = ($BMP['width']*$BMP['bytes_per_pixel']/4); |
||||
|
$BMP['decal'] -= floor($BMP['width']*$BMP['bytes_per_pixel']/4); |
||||
|
$BMP['decal'] = 4-(4*$BMP['decal']); |
||||
|
if ($BMP['decal'] == 4) $BMP['decal'] = 0; |
||||
|
|
||||
// creates image data |
$PALETTE = array(); |
||||
$bgfillcolor = array('red'=>0, 'green'=>0, 'blue'=>0); |
if ($BMP['colors'] < 16777216) |
||||
|
{ |
||||
|
$PALETTE = unpack('V'.$BMP['colors'], fread($f1,$BMP['colors']*4)); |
||||
|
} |
||||
|
|
||||
// bottom to top - left to right - attention blue green red !!! |
$IMG = fread($f1,$BMP['size_bitmap']); |
||||
$y=$height-1; |
$VIDE = chr(0); |
||||
for ($y2=0; $y2<$height; $y2++) { |
|
||||
for ($x=0; $x<$widthFloor; ) { |
|
||||
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
|
||||
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
|
||||
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
|
||||
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
|
||||
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
|
||||
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
|
||||
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
|
||||
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
|
||||
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
|
||||
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
|
||||
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
|
||||
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
|
||||
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
|
||||
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
|
||||
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
|
||||
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
|
||||
} |
|
||||
for ($x=$widthFloor; $x<$widthCeil; $x++) { |
|
||||
$rgb = ($x<$widthOrig) ? imagecolorsforindex($img, imagecolorat($img, $x, $y)) : $bgfillcolor; |
|
||||
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
|
||||
} |
|
||||
$y--; |
|
||||
} |
|
||||
|
|
||||
// see imagegif |
$res = imagecreatetruecolor($BMP['width'],$BMP['height']); |
||||
if($filename == '') { |
$P = 0; |
||||
echo $result; |
$Y = $BMP['height']-1; |
||||
} else { |
while ($Y >= 0) |
||||
$file = fopen($filename, 'wb'); |
{ |
||||
fwrite($file, $result); |
$X=0; |
||||
fclose($file); |
while ($X < $BMP['width']) |
||||
} |
{ |
||||
|
if ($BMP['bits_per_pixel'] == 24) |
||||
|
$COLOR = unpack("V",substr($IMG,$P,3).$VIDE); |
||||
|
elseif ($BMP['bits_per_pixel'] == 16) |
||||
|
{ |
||||
|
$COLOR = unpack("n",substr($IMG,$P,2)); |
||||
|
$COLOR[1] = $PALETTE[$COLOR[1]+1]; |
||||
|
} |
||||
|
elseif ($BMP['bits_per_pixel'] == 8) |
||||
|
{ |
||||
|
$COLOR = unpack("n",$VIDE.substr($IMG,$P,1)); |
||||
|
$COLOR[1] = $PALETTE[$COLOR[1]+1]; |
||||
|
} |
||||
|
elseif ($BMP['bits_per_pixel'] == 4) |
||||
|
{ |
||||
|
$COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1)); |
||||
|
if (($P*2)%2 == 0) $COLOR[1] = ($COLOR[1] >> 4) ; else $COLOR[1] = ($COLOR[1] & 0x0F); |
||||
|
$COLOR[1] = $PALETTE[$COLOR[1]+1]; |
||||
|
} |
||||
|
elseif ($BMP['bits_per_pixel'] == 1) |
||||
|
{ |
||||
|
$COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1)); |
||||
|
if (($P*8)%8 == 0) $COLOR[1] = $COLOR[1] >>7; |
||||
|
elseif (($P*8)%8 == 1) $COLOR[1] = ($COLOR[1] & 0x40)>>6; |
||||
|
elseif (($P*8)%8 == 2) $COLOR[1] = ($COLOR[1] & 0x20)>>5; |
||||
|
elseif (($P*8)%8 == 3) $COLOR[1] = ($COLOR[1] & 0x10)>>4; |
||||
|
elseif (($P*8)%8 == 4) $COLOR[1] = ($COLOR[1] & 0x8)>>3; |
||||
|
elseif (($P*8)%8 == 5) $COLOR[1] = ($COLOR[1] & 0x4)>>2; |
||||
|
elseif (($P*8)%8 == 6) $COLOR[1] = ($COLOR[1] & 0x2)>>1; |
||||
|
elseif (($P*8)%8 == 7) $COLOR[1] = ($COLOR[1] & 0x1); |
||||
|
$COLOR[1] = $PALETTE[$COLOR[1]+1]; |
||||
|
} |
||||
|
else |
||||
|
return FALSE; |
||||
|
imagesetpixel($res,$X,$Y,$COLOR[1]); |
||||
|
$X++; |
||||
|
$P += $BMP['bytes_per_pixel']; |
||||
} |
} |
||||
// imagebmp helpers |
$Y--; |
||||
function int_to_dword($n) { |
$P+=$BMP['decal']; |
||||
return chr($n & 255).chr(($n >> 8) & 255).chr(($n >> 16) & 255).chr(($n >> 24) & 255); |
} |
||||
|
fclose($f1); |
||||
|
|
||||
|
return $res; |
||||
|
} |
||||
|
|
||||
|
function imagebmp(&$img, $filename='') { |
||||
|
$widthOrig = imagesx($img); |
||||
|
$widthFloor = ((floor($widthOrig/16))*16); |
||||
|
$widthCeil = ((ceil($widthOrig/16))*16); |
||||
|
$height = imagesy($img); |
||||
|
|
||||
|
$size = ($widthCeil*$height*3)+54; |
||||
|
|
||||
|
// Bitmap File Header |
||||
|
$result = 'BM'; // header (2b) |
||||
|
$result .= int_to_dword($size); // size of file (4b) |
||||
|
$result .= int_to_dword(0); // reserved (4b) |
||||
|
$result .= int_to_dword(54); // byte location in the file which is first byte of IMAGE (4b) |
||||
|
// Bitmap Info Header |
||||
|
$result .= int_to_dword(40); // Size of BITMAPINFOHEADER (4b) |
||||
|
$result .= int_to_dword($widthCeil); // width of bitmap (4b) |
||||
|
$result .= int_to_dword($height); // height of bitmap (4b) |
||||
|
$result .= int_to_word(1); // biPlanes = 1 (2b) |
||||
|
$result .= int_to_word(24); // biBitCount = {1 (mono) or 4 (16 clr ) or 8 (256 clr) or 24 (16 Mil)} (2b |
||||
|
$result .= int_to_dword(0); // RLE COMPRESSION (4b) |
||||
|
$result .= int_to_dword(0); // width x height (4b) |
||||
|
$result .= int_to_dword(0); // biXPelsPerMeter (4b) |
||||
|
$result .= int_to_dword(0); // biYPelsPerMeter (4b) |
||||
|
$result .= int_to_dword(0); // Number of palettes used (4b) |
||||
|
$result .= int_to_dword(0); // Number of important colour (4b) |
||||
|
|
||||
|
// is faster than chr() |
||||
|
$arrChr = array(); |
||||
|
for($i=0; $i<256; $i++){ |
||||
|
$arrChr[$i] = chr($i); |
||||
} |
} |
||||
function int_to_word($n) { |
|
||||
return chr($n & 255).chr(($n >> 8) & 255); |
// creates image data |
||||
|
$bgfillcolor = array('red'=>0, 'green'=>0, 'blue'=>0); |
||||
|
|
||||
|
// bottom to top - left to right - attention blue green red !!! |
||||
|
$y=$height-1; |
||||
|
for ($y2=0; $y2<$height; $y2++) { |
||||
|
for ($x=0; $x<$widthFloor; ) { |
||||
|
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
||||
|
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
||||
|
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
||||
|
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
||||
|
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
||||
|
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
||||
|
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
||||
|
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
||||
|
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
||||
|
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
||||
|
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
||||
|
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
||||
|
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
||||
|
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
||||
|
$rgb = imagecolorsforindex($img, imagecolorat($img, $x++, $y)); |
||||
|
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
||||
|
} |
||||
|
for ($x=$widthFloor; $x<$widthCeil; $x++) { |
||||
|
$rgb = ($x<$widthOrig) ? imagecolorsforindex($img, imagecolorat($img, $x, $y)) : $bgfillcolor; |
||||
|
$result .= $arrChr[$rgb['blue']].$arrChr[$rgb['green']].$arrChr[$rgb['red']]; |
||||
|
} |
||||
|
$y--; |
||||
|
} |
||||
|
|
||||
|
// see imagegif |
||||
|
if($filename == '') { |
||||
|
echo $result; |
||||
|
} else { |
||||
|
$file = fopen($filename, 'wb'); |
||||
|
fwrite($file, $result); |
||||
|
fclose($file); |
||||
} |
} |
||||
|
} |
||||
|
// imagebmp helpers |
||||
|
function int_to_dword($n) { |
||||
|
return chr($n & 255).chr(($n >> 8) & 255).chr(($n >> 16) & 255).chr(($n >> 24) & 255); |
||||
|
} |
||||
|
function int_to_word($n) { |
||||
|
return chr($n & 255).chr(($n >> 8) & 255); |
||||
|
} |
||||
|
|
||||
?> |
|
||||
|
@ -1,283 +1,287 @@ |
|||||
<?php |
<?php |
||||
if($_SERVER['SCRIPT_FILENAME'] == str_replace('\\', '/', __FILE__)) { |
|
||||
// You cannot request this file directly. |
/* |
||||
header('Location: ../', true, 302); |
* Copyright (c) 2010-2012 Tinyboard Development Group |
||||
exit; |
*/ |
||||
} |
|
||||
|
if(realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) { |
||||
|
// You cannot request this file directly. |
||||
|
exit; |
||||
|
} |
||||
|
|
||||
|
// create a hash/salt pair for validate logins |
||||
|
function mkhash($username, $password, $salt = false) { |
||||
|
global $config; |
||||
|
|
||||
// create a hash/salt pair for validate logins |
if(!$salt) { |
||||
function mkhash($username, $password, $salt = false) { |
// create some sort of salt for the hash |
||||
global $config; |
$salt = substr(base64_encode(sha1(rand() . time(), true) . $config['cookies']['salt']), 0, 15); |
||||
|
|
||||
if(!$salt) { |
|
||||
// create some sort of salt for the hash |
|
||||
$salt = substr(base64_encode(sha1(rand() . time(), true) . $config['cookies']['salt']), 0, 15); |
|
||||
|
|
||||
$generated_salt = true; |
|
||||
} |
|
||||
|
|
||||
// generate hash (method is not important as long as it's strong) |
$generated_salt = true; |
||||
$hash = substr(base64_encode(md5($username . sha1($username . $password . $salt . ($config['mod']['lock_ip'] ? $_SERVER['REMOTE_ADDR'] : ''), true), true)), 0, 20); |
|
||||
|
|
||||
if(isset($generated_salt)) |
|
||||
return Array($hash, $salt); |
|
||||
else |
|
||||
return $hash; |
|
||||
} |
} |
||||
|
|
||||
function login($username, $password, $makehash=true) { |
// generate hash (method is not important as long as it's strong) |
||||
global $mod; |
$hash = substr(base64_encode(md5($username . sha1($username . $password . $salt . ($config['mod']['lock_ip'] ? $_SERVER['REMOTE_ADDR'] : ''), true), true)), 0, 20); |
||||
|
|
||||
// SHA1 password |
|
||||
if($makehash) { |
|
||||
$password = sha1($password); |
|
||||
} |
|
||||
|
|
||||
$query = prepare("SELECT `id`,`type`,`boards` FROM `mods` WHERE `username` = :username AND `password` = :password LIMIT 1"); |
|
||||
$query->bindValue(':username', $username); |
|
||||
$query->bindValue(':password', $password); |
|
||||
$query->execute() or error(db_error($query)); |
|
||||
|
|
||||
if($user = $query->fetch()) { |
|
||||
return $mod = Array( |
|
||||
'id' => $user['id'], |
|
||||
'type' => $user['type'], |
|
||||
'username' => $username, |
|
||||
'hash' => mkhash($username, $password), |
|
||||
'boards' => explode(',', $user['boards']) |
|
||||
); |
|
||||
} else return false; |
|
||||
} |
|
||||
|
|
||||
function setCookies() { |
if(isset($generated_salt)) |
||||
global $mod, $config; |
return Array($hash, $salt); |
||||
if(!$mod) |
else |
||||
error('setCookies() was called for a non-moderator!'); |
return $hash; |
||||
|
} |
||||
setcookie($config['cookies']['mod'], |
|
||||
$mod['username'] . // username |
function login($username, $password, $makehash=true) { |
||||
':' . |
global $mod; |
||||
$mod['hash'][0] . // password |
|
||||
':' . |
|
||||
$mod['hash'][1], // salt |
|
||||
time() + $config['cookies']['expire'], $config['cookies']['jail'] ? $config['cookies']['path'] : '/', null, false, true); |
|
||||
} |
|
||||
|
|
||||
function destroyCookies() { |
// SHA1 password |
||||
global $config; |
if($makehash) { |
||||
// Delete the cookies |
$password = sha1($password); |
||||
setcookie($config['cookies']['mod'], 'deleted', time() - $config['cookies']['expire'], $config['cookies']['jail']?$config['cookies']['path'] : '/', null, false, true); |
|
||||
} |
} |
||||
|
|
||||
function create_pm_header() { |
$query = prepare("SELECT `id`,`type`,`boards` FROM `mods` WHERE `username` = :username AND `password` = :password LIMIT 1"); |
||||
global $mod; |
$query->bindValue(':username', $username); |
||||
$query = prepare("SELECT `id` FROM `pms` WHERE `to` = :id AND `unread` = 1"); |
$query->bindValue(':password', $password); |
||||
$query->bindValue(':id', $mod['id'], PDO::PARAM_INT); |
$query->execute() or error(db_error($query)); |
||||
$query->execute() or error(db_error($query)); |
|
||||
|
if($user = $query->fetch()) { |
||||
if($pm = $query->fetch()) { |
return $mod = Array( |
||||
return Array('id' => $pm['id'], 'waiting' => $query->rowCount() - 1); |
'id' => $user['id'], |
||||
} |
'type' => $user['type'], |
||||
|
'username' => $username, |
||||
return false; |
'hash' => mkhash($username, $password), |
||||
|
'boards' => explode(',', $user['boards']) |
||||
|
); |
||||
|
} else return false; |
||||
|
} |
||||
|
|
||||
|
function setCookies() { |
||||
|
global $mod, $config; |
||||
|
if(!$mod) |
||||
|
error('setCookies() was called for a non-moderator!'); |
||||
|
|
||||
|
setcookie($config['cookies']['mod'], |
||||
|
$mod['username'] . // username |
||||
|
':' . |
||||
|
$mod['hash'][0] . // password |
||||
|
':' . |
||||
|
$mod['hash'][1], // salt |
||||
|
time() + $config['cookies']['expire'], $config['cookies']['jail'] ? $config['cookies']['path'] : '/', null, false, true); |
||||
|
} |
||||
|
|
||||
|
function destroyCookies() { |
||||
|
global $config; |
||||
|
// Delete the cookies |
||||
|
setcookie($config['cookies']['mod'], 'deleted', time() - $config['cookies']['expire'], $config['cookies']['jail']?$config['cookies']['path'] : '/', null, false, true); |
||||
|
} |
||||
|
|
||||
|
function create_pm_header() { |
||||
|
global $mod; |
||||
|
$query = prepare("SELECT `id` FROM `pms` WHERE `to` = :id AND `unread` = 1"); |
||||
|
$query->bindValue(':id', $mod['id'], PDO::PARAM_INT); |
||||
|
$query->execute() or error(db_error($query)); |
||||
|
|
||||
|
if($pm = $query->fetch()) { |
||||
|
return Array('id' => $pm['id'], 'waiting' => $query->rowCount() - 1); |
||||
} |
} |
||||
|
|
||||
function modLog($action, $_board=null) { |
return false; |
||||
global $mod, $board, $config; |
} |
||||
$query = prepare("INSERT INTO `modlogs` VALUES (:id, :ip, :board, :time, :text)"); |
|
||||
$query->bindValue(':id', $mod['id'], PDO::PARAM_INT); |
function modLog($action, $_board=null) { |
||||
$query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); |
global $mod, $board, $config; |
||||
$query->bindValue(':time', time(), PDO::PARAM_INT); |
$query = prepare("INSERT INTO `modlogs` VALUES (:id, :ip, :board, :time, :text)"); |
||||
$query->bindValue(':text', $action); |
$query->bindValue(':id', $mod['id'], PDO::PARAM_INT); |
||||
if(isset($_board)) |
$query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); |
||||
$query->bindValue(':board', $_board); |
$query->bindValue(':time', time(), PDO::PARAM_INT); |
||||
elseif(isset($board)) |
$query->bindValue(':text', $action); |
||||
$query->bindValue(':board', $board['id']); |
if(isset($_board)) |
||||
else |
$query->bindValue(':board', $_board); |
||||
$query->bindValue(':board', null, PDO::PARAM_NULL); |
elseif(isset($board)) |
||||
$query->execute() or error(db_error($query)); |
$query->bindValue(':board', $board['id']); |
||||
|
else |
||||
if($config['syslog']) |
$query->bindValue(':board', null, PDO::PARAM_NULL); |
||||
_syslog(LOG_INFO, '[mod/' . $mod['username'] . ']: ' . $action); |
$query->execute() or error(db_error($query)); |
||||
|
|
||||
|
if($config['syslog']) |
||||
|
_syslog(LOG_INFO, '[mod/' . $mod['username'] . ']: ' . $action); |
||||
|
} |
||||
|
|
||||
|
// Generates a <ul> element with a list of linked |
||||
|
// boards and their subtitles. (without the <ul> opening and ending tags) |
||||
|
function ulBoards() { |
||||
|
global $mod, $config; |
||||
|
|
||||
|
$body = ''; |
||||
|
|
||||
|
// List of boards |
||||
|
$boards = listBoards(); |
||||
|
|
||||
|
foreach($boards as &$b) { |
||||
|
$body .= '<li>' . |
||||
|
'<a href="?/' . |
||||
|
sprintf($config['board_path'], $b['uri']) . $config['file_index'] . |
||||
|
'">' . |
||||
|
sprintf($config['board_abbreviation'], $b['uri']) . |
||||
|
'</a> - ' . |
||||
|
$b['title'] . |
||||
|
(isset($b['subtitle']) ? '<span class="unimportant"> — ' . $b['subtitle'] . '</span>' : '') . |
||||
|
($mod['type'] >= $config['mod']['manageboards'] ? |
||||
|
' <a href="?/board/' . $b['uri'] . '" class="unimportant">[manage]</a>' : '') . |
||||
|
'</li>'; |
||||
} |
} |
||||
|
|
||||
// Generates a <ul> element with a list of linked |
if($mod['type'] >= $config['mod']['newboard']) { |
||||
// boards and their subtitles. (without the <ul> opening and ending tags) |
$body .= '<li style="margin-top:15px;"><a href="?/new"><strong>' . _('Create new board') . '</strong></a></li>'; |
||||
function ulBoards() { |
|
||||
global $mod, $config; |
|
||||
|
|
||||
$body = ''; |
|
||||
|
|
||||
// List of boards |
|
||||
$boards = listBoards(); |
|
||||
|
|
||||
foreach($boards as &$b) { |
|
||||
$body .= '<li>' . |
|
||||
'<a href="?/' . |
|
||||
sprintf($config['board_path'], $b['uri']) . $config['file_index'] . |
|
||||
'">' . |
|
||||
sprintf($config['board_abbreviation'], $b['uri']) . |
|
||||
'</a> - ' . |
|
||||
$b['title'] . |
|
||||
(isset($b['subtitle']) ? '<span class="unimportant"> — ' . $b['subtitle'] . '</span>' : '') . |
|
||||
($mod['type'] >= $config['mod']['manageboards'] ? |
|
||||
' <a href="?/board/' . $b['uri'] . '" class="unimportant">[manage]</a>' : '') . |
|
||||
'</li>'; |
|
||||
} |
|
||||
|
|
||||
if($mod['type'] >= $config['mod']['newboard']) { |
|
||||
$body .= '<li style="margin-top:15px;"><a href="?/new"><strong>' . _('Create new board') . '</strong></a></li>'; |
|
||||
} |
|
||||
return $body; |
|
||||
} |
} |
||||
|
return $body; |
||||
|
} |
||||
|
|
||||
|
function form_newBan($ip=null, $reason='', $continue=false, $delete=false, $board=false, $allow_public = false) { |
||||
|
global $config, $mod; |
||||
|
|
||||
function form_newBan($ip=null, $reason='', $continue=false, $delete=false, $board=false, $allow_public = false) { |
$boards = listBoards(); |
||||
global $config, $mod; |
$__boards = '<li><input type="radio" checked="checked" name="board_id" id="board_*" value="-1"/> <label style="display:inline" for="board_*"><em>' . _('all boards') . '</em></label></li>'; |
||||
|
foreach($boards as &$_board) { |
||||
$boards = listBoards(); |
$__boards .= '<li>' . |
||||
$__boards = '<li><input type="radio" checked="checked" name="board_id" id="board_*" value="-1"/> <label style="display:inline" for="board_*"><em>' . _('all boards') . '</em></label></li>'; |
'<input type="radio" name="board_id" id="board_' . $_board['uri'] . '" value="' . $_board['id'] . '">' . |
||||
foreach($boards as &$_board) { |
'<label style="display:inline" for="board_' . $_board['uri'] . '"> ' . |
||||
$__boards .= '<li>' . |
($_board['uri'] == '*' ? |
||||
'<input type="radio" name="board_id" id="board_' . $_board['uri'] . '" value="' . $_board['id'] . '">' . |
'<em>"*"</em>' |
||||
'<label style="display:inline" for="board_' . $_board['uri'] . '"> ' . |
: |
||||
($_board['uri'] == '*' ? |
sprintf($config['board_abbreviation'], $_board['uri']) |
||||
'<em>"*"</em>' |
) . |
||||
: |
' - ' . $_board['title'] . |
||||
sprintf($config['board_abbreviation'], $_board['uri']) |
'</label>' . |
||||
) . |
'</li>'; |
||||
' - ' . $_board['title'] . |
|
||||
'</label>' . |
|
||||
'</li>'; |
|
||||
} |
|
||||
|
|
||||
return '<fieldset><legend>New ban</legend>' . |
|
||||
'<form action="?/ban" method="post">' . |
|
||||
($continue ? '<input type="hidden" name="continue" value="' . htmlentities($continue) . '" />' : '') . |
|
||||
($delete || $allow_public ? '<input type="hidden" name="' . (!$allow_public ? 'delete' : 'post') . '" value="' . htmlentities($delete) . '" />' : '') . |
|
||||
($board ? '<input type="hidden" name="board" value="' . htmlentities($board) . '" />' : '') . |
|
||||
'<table>' . |
|
||||
'<tr>' . |
|
||||
'<th><label for="ip">IP ' . |
|
||||
($config['ban_cidr'] ? '<span class="unimportant">(or subnet)' : '') . |
|
||||
'</span></label></th>' . |
|
||||
'<td><input type="text" name="ip" id="ip" size="30" maxlength="30" ' . |
|
||||
(isset($ip) ? |
|
||||
'value="' . htmlentities($ip) . '" ' : '' |
|
||||
) . |
|
||||
'/></td>' . |
|
||||
'</tr>' . |
|
||||
'<tr>' . |
|
||||
'<th><label for="reason">Reason</label></th>' . |
|
||||
'<td><textarea name="reason" id="reason" rows="5" cols="30">' . |
|
||||
htmlentities($reason) . |
|
||||
'</textarea></td>' . |
|
||||
'</tr>' . |
|
||||
($mod['type'] >= $config['mod']['public_ban'] && $allow_public ? |
|
||||
'<tr>' . |
|
||||
'<th><label for="message">Message</label></th>' . |
|
||||
'<td><input type="checkbox" id="public_message" name="public_message"/>' . |
|
||||
' <input type="text" name="message" id="message" size="35" maxlength="200" value="' . htmlentities($config['mod']['default_ban_message']) . '" />' . |
|
||||
' <span class="unimportant">(public; attached to post)</span></td>' . |
|
||||
'<script type="text/javascript">' . |
|
||||
'document.getElementById(\'message\').disabled = true;' . |
|
||||
'document.getElementById(\'public_message\').onchange = function() {' . |
|
||||
'document.getElementById(\'message\').disabled = !this.checked;' . |
|
||||
'}' . |
|
||||
|
|
||||
'</script>' . |
|
||||
'</tr>' |
|
||||
: '') . |
|
||||
'<tr>' . |
|
||||
'<th><label for="length">Length</label></th>' . |
|
||||
'<td><input type="text" name="length" id="length" size="20" maxlength="40" />' . |
|
||||
' <span class="unimportant">(eg. "2d1h30m" or "2 days")</span></td>' . |
|
||||
'</tr>' . |
|
||||
|
|
||||
'<tr>' . |
|
||||
'<th>Board</th>' . |
|
||||
'<td><ul style="list-style:none;padding:2px 5px">' . $__boards . '</tl></td>' . |
|
||||
'</tr>' . |
|
||||
|
|
||||
'<tr>' . |
|
||||
'<td></td>' . |
|
||||
'<td><input name="new_ban" type="submit" value="New Ban" /></td>' . |
|
||||
'</tr>' . |
|
||||
'</table>' . |
|
||||
'</form>' . |
|
||||
'</fieldset>'; |
|
||||
} |
} |
||||
|
|
||||
function form_newBoard() { |
return '<fieldset><legend>New ban</legend>' . |
||||
return '<fieldset><legend>New board</legend>' . |
'<form action="?/ban" method="post">' . |
||||
'<form action="?/new" method="post">' . |
($continue ? '<input type="hidden" name="continue" value="' . htmlentities($continue) . '" />' : '') . |
||||
'<table>' . |
($delete || $allow_public ? '<input type="hidden" name="' . (!$allow_public ? 'delete' : 'post') . '" value="' . htmlentities($delete) . '" />' : '') . |
||||
'<tr>' . |
($board ? '<input type="hidden" name="board" value="' . htmlentities($board) . '" />' : '') . |
||||
'<th><label for="board">URI</label></th>' . |
'<table>' . |
||||
'<td><input type="text" name="uri" id="board" size="10" />' . |
'<tr>' . |
||||
' <span class="unimportant">(eg. "b"; "mu")</span></td>' . |
'<th><label for="ip">IP ' . |
||||
'</tr>' . |
($config['ban_cidr'] ? '<span class="unimportant">(or subnet)' : '') . |
||||
'<tr>' . |
'</span></label></th>' . |
||||
'<th><label for="title">Title</label></th>' . |
'<td><input type="text" name="ip" id="ip" size="30" maxlength="30" ' . |
||||
'<td><input type="text" name="title" id="title" size="25" />' . |
(isset($ip) ? |
||||
' <span class="unimportant">(eg. "Random")</span></td>' . |
'value="' . htmlentities($ip) . '" ' : '' |
||||
'</tr>' . |
) . |
||||
'<tr>' . |
'/></td>' . |
||||
'<th><label for="subtitle">Subtitle</label></th>' . |
'</tr>' . |
||||
'<td><input type="text" name="subtitle" id="subtitle" size="25" />' . |
'<tr>' . |
||||
' <span class="unimportant">(optional)</span></td>' . |
'<th><label for="reason">Reason</label></th>' . |
||||
'</tr>' . |
'<td><textarea name="reason" id="reason" rows="5" cols="30">' . |
||||
|
htmlentities($reason) . |
||||
|
'</textarea></td>' . |
||||
|
'</tr>' . |
||||
|
($mod['type'] >= $config['mod']['public_ban'] && $allow_public ? |
||||
'<tr>' . |
'<tr>' . |
||||
'<td></td>' . |
'<th><label for="message">Message</label></th>' . |
||||
'<td><input name="new_board" type="submit" value="New Board" /></td>' . |
'<td><input type="checkbox" id="public_message" name="public_message"/>' . |
||||
'</tr>' . |
' <input type="text" name="message" id="message" size="35" maxlength="200" value="' . htmlentities($config['mod']['default_ban_message']) . '" />' . |
||||
'</table>' . |
' <span class="unimportant">(public; attached to post)</span></td>' . |
||||
'</form>' . |
'<script type="text/javascript">' . |
||||
'</fieldset>'; |
'document.getElementById(\'message\').disabled = true;' . |
||||
} |
'document.getElementById(\'public_message\').onchange = function() {' . |
||||
|
'document.getElementById(\'message\').disabled = !this.checked;' . |
||||
|
'}' . |
||||
|
|
||||
|
'</script>' . |
||||
|
'</tr>' |
||||
|
: '') . |
||||
|
'<tr>' . |
||||
|
'<th><label for="length">Length</label></th>' . |
||||
|
'<td><input type="text" name="length" id="length" size="20" maxlength="40" />' . |
||||
|
' <span class="unimportant">(eg. "2d1h30m" or "2 days")</span></td>' . |
||||
|
'</tr>' . |
||||
|
|
||||
|
'<tr>' . |
||||
|
'<th>Board</th>' . |
||||
|
'<td><ul style="list-style:none;padding:2px 5px">' . $__boards . '</tl></td>' . |
||||
|
'</tr>' . |
||||
|
|
||||
|
'<tr>' . |
||||
|
'<td></td>' . |
||||
|
'<td><input name="new_ban" type="submit" value="New Ban" /></td>' . |
||||
|
'</tr>' . |
||||
|
'</table>' . |
||||
|
'</form>' . |
||||
|
'</fieldset>'; |
||||
|
} |
||||
|
|
||||
|
function form_newBoard() { |
||||
|
return '<fieldset><legend>New board</legend>' . |
||||
|
'<form action="?/new" method="post">' . |
||||
|
'<table>' . |
||||
|
'<tr>' . |
||||
|
'<th><label for="board">URI</label></th>' . |
||||
|
'<td><input type="text" name="uri" id="board" size="10" />' . |
||||
|
' <span class="unimportant">(eg. "b"; "mu")</span></td>' . |
||||
|
'</tr>' . |
||||
|
'<tr>' . |
||||
|
'<th><label for="title">Title</label></th>' . |
||||
|
'<td><input type="text" name="title" id="title" size="25" />' . |
||||
|
' <span class="unimportant">(eg. "Random")</span></td>' . |
||||
|
'</tr>' . |
||||
|
'<tr>' . |
||||
|
'<th><label for="subtitle">Subtitle</label></th>' . |
||||
|
'<td><input type="text" name="subtitle" id="subtitle" size="25" />' . |
||||
|
' <span class="unimportant">(optional)</span></td>' . |
||||
|
'</tr>' . |
||||
|
'<tr>' . |
||||
|
'<td></td>' . |
||||
|
'<td><input name="new_board" type="submit" value="New Board" /></td>' . |
||||
|
'</tr>' . |
||||
|
'</table>' . |
||||
|
'</form>' . |
||||
|
'</fieldset>'; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
function removeBan($id) { |
||||
|
global $config, $memcached; |
||||
|
|
||||
|
$query = prepare("DELETE FROM `bans` WHERE `id` = :id"); |
||||
|
$query->bindValue(':id', $id, PDO::PARAM_INT); |
||||
|
$query->execute() or error(db_error($query)); |
||||
|
|
||||
function removeBan($id) { |
//if($config['memcached']['enabled']) { |
||||
global $config, $memcached; |
// Remove cached ban |
||||
|
// TODO |
||||
$query = prepare("DELETE FROM `bans` WHERE `id` = :id"); |
// $memcached->delete("ban_{$id}"); |
||||
$query->bindValue(':id', $id, PDO::PARAM_INT); |
//} |
||||
$query->execute() or error(db_error($query)); |
} |
||||
|
|
||||
//if($config['memcached']['enabled']) { |
|
||||
// Remove cached ban |
// Validate session |
||||
// TODO |
|
||||
// $memcached->delete("ban_{$id}"); |
if(isset($_COOKIE[$config['cookies']['mod']])) { |
||||
//} |
// Should be username:hash:salt |
||||
|
$cookie = explode(':', $_COOKIE[$config['cookies']['mod']]); |
||||
|
if(count($cookie) != 3) { |
||||
|
destroyCookies(); |
||||
|
error($config['error']['malformed']); |
||||
} |
} |
||||
|
|
||||
|
$query = prepare("SELECT `id`, `type`, `boards`, `password` FROM `mods` WHERE `username` = :username LIMIT 1"); |
||||
|
$query->bindValue(':username', $cookie[0]); |
||||
|
$query->execute() or error(db_error($query)); |
||||
|
$user = $query->fetch(); |
||||
|
|
||||
// Validate session |
// validate password hash |
||||
|
if($cookie[1] != mkhash($cookie[0], $user['password'], $cookie[2])) { |
||||
if(isset($_COOKIE[$config['cookies']['mod']])) { |
// Malformed cookies |
||||
// Should be username:hash:salt |
destroyCookies(); |
||||
$cookie = explode(':', $_COOKIE[$config['cookies']['mod']]); |
error($config['error']['malformed']); |
||||
if(count($cookie) != 3) { |
|
||||
destroyCookies(); |
|
||||
error($config['error']['malformed']); |
|
||||
} |
|
||||
|
|
||||
$query = prepare("SELECT `id`, `type`, `boards`, `password` FROM `mods` WHERE `username` = :username LIMIT 1"); |
|
||||
$query->bindValue(':username', $cookie[0]); |
|
||||
$query->execute() or error(db_error($query)); |
|
||||
$user = $query->fetch(); |
|
||||
|
|
||||
// validate password hash |
|
||||
if($cookie[1] != mkhash($cookie[0], $user['password'], $cookie[2])) { |
|
||||
// Malformed cookies |
|
||||
destroyCookies(); |
|
||||
error($config['error']['malformed']); |
|
||||
} |
|
||||
|
|
||||
$mod = Array( |
|
||||
'id' => $user['id'], |
|
||||
'type' => $user['type'], |
|
||||
'username' => $cookie[0], |
|
||||
'boards' => explode(',', $user['boards']) |
|
||||
); |
|
||||
} |
} |
||||
|
|
||||
|
$mod = Array( |
||||
|
'id' => $user['id'], |
||||
|
'type' => $user['type'], |
||||
|
'username' => $cookie[0], |
||||
|
'boards' => explode(',', $user['boards']) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
@ -1,57 +1,67 @@ |
|||||
<?php |
<?php |
||||
class Remote { |
|
||||
public function __construct($config) { |
/* |
||||
foreach($config as $name => $value) { |
* Copyright (c) 2010-2012 Tinyboard Development Group |
||||
$this->{$name} = $value; |
*/ |
||||
} |
|
||||
|
if(realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) { |
||||
$methods = Array(); |
// You cannot request this file directly. |
||||
|
exit; |
||||
if(!isset($this->auth['method'])) |
} |
||||
error('Unspecified authentication method.'); |
|
||||
|
class Remote { |
||||
// Connect |
public function __construct($config) { |
||||
$this->connection = ssh2_connect($this->host, isset($this->port) ? $this->port : 22, $methods); |
foreach($config as $name => $value) { |
||||
|
$this->{$name} = $value; |
||||
switch($this->auth['method']) { |
|
||||
case 'pubkey': |
|
||||
|
|
||||
if(!isset($this->auth['public'])) |
|
||||
error('Public key filename not specified.'); |
|
||||
if(!isset($this->auth['private'])) |
|
||||
error('Private key filename not specified.'); |
|
||||
|
|
||||
if(!ssh2_auth_pubkey_file($this->connection, $this->auth['username'], $this->auth['public'], $this->auth['private'], isset($this->auth['passphrase']) ? $this->auth['passphrase']: null)) |
|
||||
error('Public key authentication failed.'); |
|
||||
break; |
|
||||
case 'plain': |
|
||||
if(!ssh2_auth_password($this->connection, $this->auth['username'], $this->auth['password'])) |
|
||||
error('Plain-text authentication failed.'); |
|
||||
break; |
|
||||
default: |
|
||||
error('Unknown authentication method: "' . $this->auth['method'] . '".'); |
|
||||
} |
|
||||
|
|
||||
} |
} |
||||
|
|
||||
public function write($data, $remote_path) { |
$methods = Array(); |
||||
global $config; |
|
||||
|
if(!isset($this->auth['method'])) |
||||
switch($this->type) { |
error('Unspecified authentication method.'); |
||||
case 'sftp': |
|
||||
$sftp = ssh2_sftp($this->connection); |
// Connect |
||||
file_write('ssh2.sftp://' . $sftp . $remote_path, $data, true); |
$this->connection = ssh2_connect($this->host, isset($this->port) ? $this->port : 22, $methods); |
||||
break; |
|
||||
case 'scp': |
switch($this->auth['method']) { |
||||
$file = tempnam($config['tmp'], 'tinyboard-scp'); |
case 'pubkey': |
||||
// Write to temp file |
|
||||
file_write($file, $data); |
if(!isset($this->auth['public'])) |
||||
|
error('Public key filename not specified.'); |
||||
ssh2_scp_send($this->connection, $file, $remote_path, 0755); |
if(!isset($this->auth['private'])) |
||||
break; |
error('Private key filename not specified.'); |
||||
default: |
|
||||
error('Unknown send method.'); |
if(!ssh2_auth_pubkey_file($this->connection, $this->auth['username'], $this->auth['public'], $this->auth['private'], isset($this->auth['passphrase']) ? $this->auth['passphrase']: null)) |
||||
} |
error('Public key authentication failed.'); |
||||
|
break; |
||||
|
case 'plain': |
||||
|
if(!ssh2_auth_password($this->connection, $this->auth['username'], $this->auth['password'])) |
||||
|
error('Plain-text authentication failed.'); |
||||
|
break; |
||||
|
default: |
||||
|
error('Unknown authentication method: "' . $this->auth['method'] . '".'); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public function write($data, $remote_path) { |
||||
|
global $config; |
||||
|
|
||||
|
switch($this->type) { |
||||
|
case 'sftp': |
||||
|
$sftp = ssh2_sftp($this->connection); |
||||
|
file_write('ssh2.sftp://' . $sftp . $remote_path, $data, true); |
||||
|
break; |
||||
|
case 'scp': |
||||
|
$file = tempnam($config['tmp'], 'tinyboard-scp'); |
||||
|
// Write to temp file |
||||
|
file_write($file, $data); |
||||
|
|
||||
|
ssh2_scp_send($this->connection, $file, $remote_path, 0755); |
||||
|
break; |
||||
|
default: |
||||
|
error('Unknown send method.'); |
||||
} |
} |
||||
}; |
} |
||||
?> |
}; |
||||
|
|
||||
|
@ -1,57 +1,72 @@ |
|||||
<?php |
<?php |
||||
if($_SERVER['SCRIPT_FILENAME'] == str_replace('\\', '/', __FILE__)) { |
|
||||
// You cannot request this file directly. |
/* |
||||
header('Location: ../', true, 302); |
* Copyright (c) 2010-2012 Tinyboard Development Group |
||||
exit; |
*/ |
||||
} |
|
||||
|
if(realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) { |
||||
|
// You cannot request this file directly. |
||||
|
exit; |
||||
|
} |
||||
|
|
||||
|
$twig = false; |
||||
|
|
||||
|
function load_twig() { |
||||
|
global $twig, $config; |
||||
|
|
||||
require 'lib/Twig/Autoloader.php'; |
require 'lib/Twig/Autoloader.php'; |
||||
Twig_Autoloader::register(); |
Twig_Autoloader::register(); |
||||
|
|
||||
Twig_Autoloader::autoload('Twig_Extensions_Node_Trans'); |
Twig_Autoloader::autoload('Twig_Extensions_Node_Trans'); |
||||
Twig_Autoloader::autoload('Twig_Extensions_TokenParser_Trans'); |
Twig_Autoloader::autoload('Twig_Extensions_TokenParser_Trans'); |
||||
Twig_Autoloader::autoload('Twig_Extensions_Extension_I18n'); |
Twig_Autoloader::autoload('Twig_Extensions_Extension_I18n'); |
||||
Twig_Autoloader::autoload('Twig_Extensions_Extension_Tinyboard'); |
Twig_Autoloader::autoload('Twig_Extensions_Extension_Tinyboard'); |
||||
|
|
||||
$loader = new Twig_Loader_Filesystem($config['dir']['template']); |
$loader = new Twig_Loader_Filesystem($config['dir']['template']); |
||||
|
$loader->setPaths($config['dir']['template']); |
||||
|
$twig = new Twig_Environment($loader, Array( |
||||
|
'autoescape' => false, |
||||
|
'cache' => "{$config['dir']['template']}/cache", |
||||
|
'debug' => ($config['debug'] ? true : false), |
||||
|
)); |
||||
|
$twig->addExtension(new Twig_Extensions_Extension_Tinyboard()); |
||||
|
$twig->addExtension(new Twig_Extensions_Extension_I18n()); |
||||
|
} |
||||
|
|
||||
|
function Element($templateFile, array $options) { |
||||
|
global $config, $debug, $twig; |
||||
|
|
||||
function Element($templateFile, array $options) { |
if(!$twig) |
||||
global $config, $debug, $loader; |
load_twig(); |
||||
|
|
||||
if(function_exists('create_pm_header') && ((isset($options['mod']) && $options['mod']) || isset($options['__mod']))) { |
if(function_exists('create_pm_header') && ((isset($options['mod']) && $options['mod']) || isset($options['__mod']))) { |
||||
$options['pm'] = create_pm_header(); |
$options['pm'] = create_pm_header(); |
||||
|
} |
||||
|
|
||||
|
if(isset($options['body']) && $config['debug']) { |
||||
|
if(isset($debug['start'])) { |
||||
|
$debug['time'] = '~' . round((microtime(true) - $debug['start']) * 1000, 2) . 'ms'; |
||||
|
unset($debug['start']); |
||||
} |
} |
||||
|
$debug['included'] = get_included_files(); |
||||
|
$debug['memory'] = round(memory_get_usage(true) / (1024 * 1024), 2) . ' MiB'; |
||||
|
$options['body'] .= |
||||
|
'<h3>Debug</h3><pre style="white-space: pre-wrap;font-size: 10px;">' . |
||||
|
str_replace("\n", '<br/>', utf8tohtml(print_r($debug, true))) . |
||||
|
'</pre>'; |
||||
|
} |
||||
|
|
||||
|
// Read the template file |
||||
|
if(@file_get_contents("{$config['dir']['template']}/${templateFile}")) { |
||||
|
$body = $twig->render($templateFile, $options); |
||||
|
|
||||
if(isset($options['body']) && $config['debug']) { |
if($config['minify_html'] && preg_match('/\.html$/', $templateFile)) { |
||||
if(isset($debug['start'])) { |
$body = trim(preg_replace("/[\t\r\n]/", '', $body)); |
||||
$debug['time'] = '~' . round((microtime(true) - $debug['start']) * 1000, 2) . 'ms'; |
|
||||
unset($debug['start']); |
|
||||
|
|
||||
} |
|
||||
$options['body'] .= '<h3>Debug</h3><pre style="white-space: pre-wrap;font-size: 10px;">' . str_replace("\n", '<br/>', utf8tohtml(print_r($debug, true))) . '</pre>'; |
|
||||
} |
} |
||||
|
|
||||
$loader->setPaths($config['dir']['template']); |
return $body; |
||||
|
} else { |
||||
$twig = new Twig_Environment($loader, Array( |
throw new Exception("Template file '${templateFile}' does not exist or is empty in '{$config['dir']['template']}'!"); |
||||
'autoescape' => false, |
|
||||
'cache' => "{$config['dir']['template']}/cache", |
|
||||
'debug' => ($config['debug'] ? true : false), |
|
||||
)); |
|
||||
$twig->addExtension(new Twig_Extensions_Extension_Tinyboard()); |
|
||||
$twig->addExtension(new Twig_Extensions_Extension_I18n()); |
|
||||
|
|
||||
// Read the template file |
|
||||
if(@file_get_contents("{$config['dir']['template']}/${templateFile}")) { |
|
||||
$body = $twig->render($templateFile, $options); |
|
||||
|
|
||||
if($config['minify_html'] && preg_match('/\.html$/', $templateFile)) { |
|
||||
$body = trim(preg_replace("/[\t\r\n]/", '', $body)); |
|
||||
} |
|
||||
|
|
||||
return $body; |
|
||||
} else { |
|
||||
throw new Exception("Template file '${templateFile}' does not exist or is empty in '{$config['dir']['template']}'!"); |
|
||||
} |
|
||||
} |
} |
||||
?> |
} |
||||
|
|
||||
|
@ -1,10 +0,0 @@ |
|||||
<?php |
|
||||
if($_SERVER['SCRIPT_FILENAME'] == str_replace('\\', '/', __FILE__)) { |
|
||||
// You cannot request this file directly. |
|
||||
header('Location: ../', true, 302); |
|
||||
exit; |
|
||||
} |
|
||||
|
|
||||
// 'false' means that the user is not logged in as a moderator |
|
||||
$mod = false; |
|
||||
|
|
@ -1,522 +1,520 @@ |
|||||
<?php |
<?php |
||||
// Installation/upgrade file |
|
||||
define('VERSION', 'v0.9.6-dev-1'); |
// Installation/upgrade file |
||||
|
define('VERSION', 'v0.9.6-dev-1'); |
||||
require 'inc/functions.php'; |
|
||||
require 'inc/display.php'; |
require 'inc/functions.php'; |
||||
require 'inc/template.php'; |
|
||||
require 'inc/database.php'; |
$step = isset($_GET['step']) ? round($_GET['step']) : 0; |
||||
require 'inc/user.php'; |
$page = Array( |
||||
$step = isset($_GET['step']) ? round($_GET['step']) : 0; |
'config' => $config, |
||||
$page = Array( |
'title' => 'Install', |
||||
'config' => $config, |
'body' => '', |
||||
'title' => 'Install', |
'nojavascript' => true |
||||
'body' => '', |
); |
||||
'nojavascript' => true |
|
||||
); |
// this breaks the dispaly of licenses if enabled |
||||
|
$config['minify_html'] = false; |
||||
// this breaks the dispaly of licenses if enabled |
|
||||
$config['minify_html'] = false; |
if(file_exists($config['has_installed'])) { |
||||
|
|
||||
if(file_exists($config['has_installed'])) { |
// Check the version number |
||||
|
$version = trim(file_get_contents($config['has_installed'])); |
||||
// Check the version number |
if(empty($version)) |
||||
$version = trim(file_get_contents($config['has_installed'])); |
$version = 'v0.9.1'; |
||||
if(empty($version)) |
|
||||
$version = 'v0.9.1'; |
$boards = listBoards(); |
||||
|
|
||||
$boards = listBoards(); |
switch($version) { |
||||
|
case 'v0.9': |
||||
switch($version) { |
case 'v0.9.1': |
||||
case 'v0.9': |
// Upgrade to v0.9.2-dev |
||||
case 'v0.9.1': |
|
||||
// Upgrade to v0.9.2-dev |
foreach($boards as &$_board) { |
||||
|
// Add `capcode` field after `trip` |
||||
foreach($boards as &$_board) { |
query(sprintf("ALTER TABLE `posts_%s` ADD `capcode` VARCHAR( 50 ) NULL AFTER `trip`", $_board['uri'])) or error(db_error()); |
||||
// Add `capcode` field after `trip` |
|
||||
query(sprintf("ALTER TABLE `posts_%s` ADD `capcode` VARCHAR( 50 ) NULL AFTER `trip`", $_board['uri'])) or error(db_error()); |
|
||||
|
|
||||
// Resize `trip` to 15 characters |
|
||||
query(sprintf("ALTER TABLE `posts_%s` CHANGE `trip` `trip` VARCHAR( 15 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL", $_board['uri'])) or error(db_error()); |
|
||||
} |
|
||||
case 'v0.9.2-dev': |
|
||||
// Upgrade to v0.9.2-dev-1 |
|
||||
|
|
||||
// New table: `theme_settings` |
|
||||
query("CREATE TABLE IF NOT EXISTS `theme_settings` ( `name` varchar(40) NOT NULL, `value` text, UNIQUE KEY `name` (`name`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;") or error(db_error()); |
|
||||
|
|
||||
// New table: `news` |
|
||||
query("CREATE TABLE IF NOT EXISTS `news` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` text NOT NULL, `time` int(11) NOT NULL, `subject` text NOT NULL, `body` text NOT NULL, UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;") or error(db_error()); |
|
||||
case 'v0.9.2.1-dev': |
|
||||
case 'v0.9.2-dev-1': |
|
||||
// Fix broken version number/mistake |
|
||||
$version = 'v0.9.2-dev-1'; |
|
||||
// Upgrade to v0.9.2-dev-2 |
|
||||
|
|
||||
foreach($boards as &$_board) { |
|
||||
// Increase field sizes |
|
||||
query(sprintf("ALTER TABLE `posts_%s` CHANGE `subject` `subject` VARCHAR( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL", $_board['uri'])) or error(db_error()); |
|
||||
query(sprintf("ALTER TABLE `posts_%s` CHANGE `name` `name` VARCHAR( 35 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL", $_board['uri'])) or error(db_error()); |
|
||||
} |
|
||||
case 'v0.9.2-dev-2': |
|
||||
// Upgrade to v0.9.2-dev-3 (v0.9.2) |
|
||||
|
|
||||
foreach($boards as &$_board) { |
|
||||
// Add `custom_fields` field |
|
||||
query(sprintf("ALTER TABLE `posts_%s` ADD `embed` TEXT NULL", $_board['uri'])) or error(db_error()); |
|
||||
} |
|
||||
case 'v0.9.2-dev-3': // v0.9.2-dev-3 == v0.9.2 |
|
||||
case 'v0.9.2': |
|
||||
// Upgrade to v0.9.3-dev-1 |
|
||||
|
|
||||
// Upgrade `theme_settings` table |
|
||||
query("TRUNCATE TABLE `theme_settings`") or error(db_error()); |
|
||||
query("ALTER TABLE `theme_settings` ADD `theme` VARCHAR( 40 ) NOT NULL FIRST") or error(db_error()); |
|
||||
query("ALTER TABLE `theme_settings` CHANGE `name` `name` VARCHAR( 40 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL") or error(db_error()); |
|
||||
query("ALTER TABLE `theme_settings` DROP INDEX `name`") or error(db_error()); |
|
||||
case 'v0.9.3-dev-1': |
|
||||
query("ALTER TABLE `mods` ADD `boards` TEXT NOT NULL") or error(db_error()); |
|
||||
query("UPDATE `mods` SET `boards` = '*'") or error(db_error()); |
|
||||
case 'v0.9.3-dev-2': |
|
||||
foreach($boards as &$_board) { |
|
||||
query(sprintf("ALTER TABLE `posts_%s` CHANGE `filehash` `filehash` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL", $_board['uri'])) or error(db_error()); |
|
||||
} |
|
||||
case 'v0.9.3-dev-3': |
|
||||
// Board-specifc bans |
|
||||
query("ALTER TABLE `bans` ADD `board` SMALLINT NULL AFTER `reason`") or error(db_error()); |
|
||||
case 'v0.9.3-dev-4': |
|
||||
// add ban ID |
|
||||
query("ALTER TABLE `bans` ADD `id` INT NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY ( `id` ), ADD UNIQUE (`id`)"); |
|
||||
case 'v0.9.3-dev-5': |
|
||||
foreach($boards as &$_board) { |
|
||||
// Increase subject field size |
|
||||
query(sprintf("ALTER TABLE `posts_%s` CHANGE `subject` `subject` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL", $_board['uri'])) or error(db_error()); |
|
||||
} |
|
||||
case 'v0.9.3-dev-6': |
|
||||
// change to MyISAM |
|
||||
$tables = Array( |
|
||||
'bans', 'boards', 'ip_notes', 'modlogs', 'mods', 'mutes', 'noticeboard', 'pms', 'reports', 'robot', 'theme_settings', 'news' |
|
||||
); |
|
||||
foreach($boards as &$board) { |
|
||||
$tables[] = "posts_{$board['uri']}"; |
|
||||
} |
|
||||
|
|
||||
foreach($tables as &$table) { |
// Resize `trip` to 15 characters |
||||
query("ALTER TABLE `{$table}` ENGINE = MYISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci") or error(db_error()); |
query(sprintf("ALTER TABLE `posts_%s` CHANGE `trip` `trip` VARCHAR( 15 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL", $_board['uri'])) or error(db_error()); |
||||
} |
} |
||||
case 'v0.9.3-dev-7': |
case 'v0.9.2-dev': |
||||
foreach($boards as &$board) { |
// Upgrade to v0.9.2-dev-1 |
||||
query(sprintf("ALTER TABLE `posts_%s` CHANGE `filename` `filename` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL", $board['uri'])) or error(db_error()); |
|
||||
} |
// New table: `theme_settings` |
||||
case 'v0.9.3-dev-8': |
query("CREATE TABLE IF NOT EXISTS `theme_settings` ( `name` varchar(40) NOT NULL, `value` text, UNIQUE KEY `name` (`name`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;") or error(db_error()); |
||||
foreach($boards as &$board) { |
|
||||
query(sprintf("ALTER TABLE `posts_%s` ADD INDEX ( `thread` )", $board['uri'])) or error(db_error()); |
// New table: `news` |
||||
} |
query("CREATE TABLE IF NOT EXISTS `news` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` text NOT NULL, `time` int(11) NOT NULL, `subject` text NOT NULL, `body` text NOT NULL, UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;") or error(db_error()); |
||||
case 'v0.9.3-dev-9': |
case 'v0.9.2.1-dev': |
||||
foreach($boards as &$board) { |
case 'v0.9.2-dev-1': |
||||
query(sprintf("ALTER TABLE `posts_%s`ADD INDEX ( `time` )", $board['uri'])) or error(db_error()); |
// Fix broken version number/mistake |
||||
query(sprintf("ALTER TABLE `posts_%s`ADD FULLTEXT (`body`)", $board['uri'])) or error(db_error()); |
$version = 'v0.9.2-dev-1'; |
||||
} |
// Upgrade to v0.9.2-dev-2 |
||||
case 'v0.9.3-dev-10': |
|
||||
case 'v0.9.3': |
foreach($boards as &$_board) { |
||||
query("ALTER TABLE `bans` DROP INDEX `id`") or error(db_error()); |
// Increase field sizes |
||||
query("ALTER TABLE `pms` DROP INDEX `id`") or error(db_error()); |
query(sprintf("ALTER TABLE `posts_%s` CHANGE `subject` `subject` VARCHAR( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL", $_board['uri'])) or error(db_error()); |
||||
query("ALTER TABLE `boards` DROP PRIMARY KEY") or error(db_error()); |
query(sprintf("ALTER TABLE `posts_%s` CHANGE `name` `name` VARCHAR( 35 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL", $_board['uri'])) or error(db_error()); |
||||
query("ALTER TABLE `reports` DROP INDEX `id`") or error(db_error()); |
} |
||||
query("ALTER TABLE `boards` DROP INDEX `uri`") or error(db_error()); |
case 'v0.9.2-dev-2': |
||||
|
// Upgrade to v0.9.2-dev-3 (v0.9.2) |
||||
|
|
||||
|
foreach($boards as &$_board) { |
||||
|
// Add `custom_fields` field |
||||
|
query(sprintf("ALTER TABLE `posts_%s` ADD `embed` TEXT NULL", $_board['uri'])) or error(db_error()); |
||||
|
} |
||||
|
case 'v0.9.2-dev-3': // v0.9.2-dev-3 == v0.9.2 |
||||
|
case 'v0.9.2': |
||||
|
// Upgrade to v0.9.3-dev-1 |
||||
|
|
||||
|
// Upgrade `theme_settings` table |
||||
|
query("TRUNCATE TABLE `theme_settings`") or error(db_error()); |
||||
|
query("ALTER TABLE `theme_settings` ADD `theme` VARCHAR( 40 ) NOT NULL FIRST") or error(db_error()); |
||||
|
query("ALTER TABLE `theme_settings` CHANGE `name` `name` VARCHAR( 40 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL") or error(db_error()); |
||||
|
query("ALTER TABLE `theme_settings` DROP INDEX `name`") or error(db_error()); |
||||
|
case 'v0.9.3-dev-1': |
||||
|
query("ALTER TABLE `mods` ADD `boards` TEXT NOT NULL") or error(db_error()); |
||||
|
query("UPDATE `mods` SET `boards` = '*'") or error(db_error()); |
||||
|
case 'v0.9.3-dev-2': |
||||
|
foreach($boards as &$_board) { |
||||
|
query(sprintf("ALTER TABLE `posts_%s` CHANGE `filehash` `filehash` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL", $_board['uri'])) or error(db_error()); |
||||
|
} |
||||
|
case 'v0.9.3-dev-3': |
||||
|
// Board-specifc bans |
||||
|
query("ALTER TABLE `bans` ADD `board` SMALLINT NULL AFTER `reason`") or error(db_error()); |
||||
|
case 'v0.9.3-dev-4': |
||||
|
// add ban ID |
||||
|
query("ALTER TABLE `bans` ADD `id` INT NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY ( `id` ), ADD UNIQUE (`id`)"); |
||||
|
case 'v0.9.3-dev-5': |
||||
|
foreach($boards as &$_board) { |
||||
|
// Increase subject field size |
||||
|
query(sprintf("ALTER TABLE `posts_%s` CHANGE `subject` `subject` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL", $_board['uri'])) or error(db_error()); |
||||
|
} |
||||
|
case 'v0.9.3-dev-6': |
||||
|
// change to MyISAM |
||||
|
$tables = Array( |
||||
|
'bans', 'boards', 'ip_notes', 'modlogs', 'mods', 'mutes', 'noticeboard', 'pms', 'reports', 'robot', 'theme_settings', 'news' |
||||
|
); |
||||
|
foreach($boards as &$board) { |
||||
|
$tables[] = "posts_{$board['uri']}"; |
||||
|
} |
||||
|
|
||||
|
foreach($tables as &$table) { |
||||
|
query("ALTER TABLE `{$table}` ENGINE = MYISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci") or error(db_error()); |
||||
|
} |
||||
|
case 'v0.9.3-dev-7': |
||||
|
foreach($boards as &$board) { |
||||
|
query(sprintf("ALTER TABLE `posts_%s` CHANGE `filename` `filename` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL", $board['uri'])) or error(db_error()); |
||||
|
} |
||||
|
case 'v0.9.3-dev-8': |
||||
|
foreach($boards as &$board) { |
||||
|
query(sprintf("ALTER TABLE `posts_%s` ADD INDEX ( `thread` )", $board['uri'])) or error(db_error()); |
||||
|
} |
||||
|
case 'v0.9.3-dev-9': |
||||
|
foreach($boards as &$board) { |
||||
|
query(sprintf("ALTER TABLE `posts_%s`ADD INDEX ( `time` )", $board['uri'])) or error(db_error()); |
||||
|
query(sprintf("ALTER TABLE `posts_%s`ADD FULLTEXT (`body`)", $board['uri'])) or error(db_error()); |
||||
|
} |
||||
|
case 'v0.9.3-dev-10': |
||||
|
case 'v0.9.3': |
||||
|
query("ALTER TABLE `bans` DROP INDEX `id`") or error(db_error()); |
||||
|
query("ALTER TABLE `pms` DROP INDEX `id`") or error(db_error()); |
||||
|
query("ALTER TABLE `boards` DROP PRIMARY KEY") or error(db_error()); |
||||
|
query("ALTER TABLE `reports` DROP INDEX `id`") or error(db_error()); |
||||
|
query("ALTER TABLE `boards` DROP INDEX `uri`") or error(db_error()); |
||||
|
|
||||
|
query("ALTER IGNORE TABLE `robot` ADD PRIMARY KEY (`hash`)") or error(db_error()); |
||||
|
query("ALTER TABLE `bans` ADD FULLTEXT (`ip`)") or error(db_error()); |
||||
|
query("ALTER TABLE `ip_notes` ADD INDEX (`ip`)") or error(db_error()); |
||||
|
query("ALTER TABLE `modlogs` ADD INDEX (`time`)") or error(db_error()); |
||||
|
query("ALTER TABLE `boards` ADD PRIMARY KEY(`uri`)") or error(db_error()); |
||||
|
query("ALTER TABLE `mutes` ADD INDEX (`ip`)") or error(db_error()); |
||||
|
query("ALTER TABLE `news` ADD INDEX (`time`)") or error(db_error()); |
||||
|
query("ALTER TABLE `theme_settings` ADD INDEX (`theme`)") or error(db_error()); |
||||
|
case 'v0.9.4-dev-1': |
||||
|
foreach($boards as &$board) { |
||||
|
query(sprintf("ALTER TABLE `posts_%s` ADD `sage` INT( 1 ) NOT NULL AFTER `locked`", $board['uri'])) or error(db_error()); |
||||
|
} |
||||
|
case 'v0.9.4-dev-2': |
||||
|
if(!isset($_GET['confirm'])) { |
||||
|
$page['title'] = 'License Change'; |
||||
|
$page['body'] = '<p style="text-align:center">You are upgrading to a version which uses an amended license. The licenses included with Tinyboard distributions prior to this version (v0.9.4-dev-2) are still valid for those versions, but no longer apply to this and newer versions.</p>' . |
||||
|
'<textarea style="width:700px;height:370px;margin:auto;display:block;background:white;color:black" disabled>' . htmlentities(file_get_contents('LICENSE.md')) . '</textarea> |
||||
|
<p style="text-align:center"> |
||||
|
<a href="?confirm=1">I have read and understood the agreement. Proceed to upgrading.</a> |
||||
|
</p>'; |
||||
|
|
||||
query("ALTER IGNORE TABLE `robot` ADD PRIMARY KEY (`hash`)") or error(db_error()); |
file_write($config['has_installed'], 'v0.9.4-dev-2'); |
||||
query("ALTER TABLE `bans` ADD FULLTEXT (`ip`)") or error(db_error()); |
|
||||
query("ALTER TABLE `ip_notes` ADD INDEX (`ip`)") or error(db_error()); |
|
||||
query("ALTER TABLE `modlogs` ADD INDEX (`time`)") or error(db_error()); |
|
||||
query("ALTER TABLE `boards` ADD PRIMARY KEY(`uri`)") or error(db_error()); |
|
||||
query("ALTER TABLE `mutes` ADD INDEX (`ip`)") or error(db_error()); |
|
||||
query("ALTER TABLE `news` ADD INDEX (`time`)") or error(db_error()); |
|
||||
query("ALTER TABLE `theme_settings` ADD INDEX (`theme`)") or error(db_error()); |
|
||||
case 'v0.9.4-dev-1': |
|
||||
foreach($boards as &$board) { |
|
||||
query(sprintf("ALTER TABLE `posts_%s` ADD `sage` INT( 1 ) NOT NULL AFTER `locked`", $board['uri'])) or error(db_error()); |
|
||||
} |
|
||||
case 'v0.9.4-dev-2': |
|
||||
if(!isset($_GET['confirm'])) { |
|
||||
$page['title'] = 'License Change'; |
|
||||
$page['body'] = '<p style="text-align:center">You are upgrading to a version which uses an amended license. The licenses included with Tinyboard distributions prior to this version (v0.9.4-dev-2) are still valid for those versions, but no longer apply to this and newer versions.</p>' . |
|
||||
'<textarea style="width:700px;height:370px;margin:auto;display:block;background:white;color:black" disabled>' . htmlentities(file_get_contents('LICENSE.md')) . '</textarea> |
|
||||
<p style="text-align:center"> |
|
||||
<a href="?confirm=1">I have read and understood the agreement. Proceed to upgrading.</a> |
|
||||
</p>'; |
|
||||
|
|
||||
file_write($config['has_installed'], 'v0.9.4-dev-2'); |
|
||||
|
|
||||
break; |
|
||||
} |
|
||||
case 'v0.9.4-dev-3': |
|
||||
case 'v0.9.4-dev-4': |
|
||||
case 'v0.9.4': |
|
||||
foreach($boards as &$board) { |
|
||||
query(sprintf("ALTER TABLE `posts_%s` |
|
||||
CHANGE `subject` `subject` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL , |
|
||||
CHANGE `email` `email` VARCHAR( 30 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL , |
|
||||
CHANGE `name` `name` VARCHAR( 35 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL", $board['uri'])) or error(db_error()); |
|
||||
} |
|
||||
case 'v0.9.5-dev-1': |
|
||||
foreach($boards as &$board) { |
|
||||
query(sprintf("ALTER TABLE `posts_%s` ADD `body_nomarkup` TEXT NULL AFTER `body`", $board['uri'])) or error(db_error()); |
|
||||
} |
|
||||
query("CREATE TABLE IF NOT EXISTS `cites` ( `board` varchar(8) NOT NULL, `post` int(11) NOT NULL, `target_board` varchar(8) NOT NULL, `target` int(11) NOT NULL, KEY `target` (`target_board`,`target`), KEY `post` (`board`,`post`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;") or error(db_error()); |
|
||||
case 'v0.9.5-dev-2': |
|
||||
query("ALTER TABLE `boards` |
|
||||
CHANGE `uri` `uri` VARCHAR( 15 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, |
|
||||
CHANGE `title` `title` VARCHAR( 40 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, |
|
||||
CHANGE `subtitle` `subtitle` VARCHAR( 120 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL") or error(db_error()); |
|
||||
case 'v0.9.5-dev-3': |
|
||||
// v0.9.5 |
|
||||
case 'v0.9.5': |
|
||||
query("ALTER TABLE `boards` |
|
||||
CHANGE `uri` `uri` VARCHAR( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, |
|
||||
CHANGE `title` `title` TINYTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, |
|
||||
CHANGE `subtitle` `subtitle` TINYTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL") or error(db_error()); |
|
||||
case false: |
|
||||
// Update version number |
|
||||
file_write($config['has_installed'], VERSION); |
|
||||
|
|
||||
$page['title'] = 'Upgraded'; |
|
||||
$page['body'] = '<p style="text-align:center">Successfully upgraded from ' . $version . ' to <strong>' . VERSION . '</strong>.</p>'; |
|
||||
break; |
|
||||
default: |
|
||||
$page['title'] = 'Unknown version'; |
|
||||
$page['body'] = '<p style="text-align:center">Tinyboard was unable to determine what version is currently installed.</p>'; |
|
||||
break; |
break; |
||||
case VERSION: |
} |
||||
$page['title'] = 'Already installed'; |
case 'v0.9.4-dev-3': |
||||
$page['body'] = '<p style="text-align:center">It appears that Tinyboard is already installed (' . $version . ') and there is nothing to upgrade! Delete <strong>' . $config['has_installed'] . '</strong> to reinstall.</p>'; |
case 'v0.9.4-dev-4': |
||||
break; |
case 'v0.9.4': |
||||
} |
foreach($boards as &$board) { |
||||
|
query(sprintf("ALTER TABLE `posts_%s` |
||||
|
CHANGE `subject` `subject` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL , |
||||
|
CHANGE `email` `email` VARCHAR( 30 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL , |
||||
|
CHANGE `name` `name` VARCHAR( 35 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL", $board['uri'])) or error(db_error()); |
||||
|
} |
||||
|
case 'v0.9.5-dev-1': |
||||
|
foreach($boards as &$board) { |
||||
|
query(sprintf("ALTER TABLE `posts_%s` ADD `body_nomarkup` TEXT NULL AFTER `body`", $board['uri'])) or error(db_error()); |
||||
|
} |
||||
|
query("CREATE TABLE IF NOT EXISTS `cites` ( `board` varchar(8) NOT NULL, `post` int(11) NOT NULL, `target_board` varchar(8) NOT NULL, `target` int(11) NOT NULL, KEY `target` (`target_board`,`target`), KEY `post` (`board`,`post`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;") or error(db_error()); |
||||
|
case 'v0.9.5-dev-2': |
||||
|
query("ALTER TABLE `boards` |
||||
|
CHANGE `uri` `uri` VARCHAR( 15 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, |
||||
|
CHANGE `title` `title` VARCHAR( 40 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, |
||||
|
CHANGE `subtitle` `subtitle` VARCHAR( 120 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL") or error(db_error()); |
||||
|
case 'v0.9.5-dev-3': |
||||
|
// v0.9.5 |
||||
|
case 'v0.9.5': |
||||
|
query("ALTER TABLE `boards` |
||||
|
CHANGE `uri` `uri` VARCHAR( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, |
||||
|
CHANGE `title` `title` TINYTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, |
||||
|
CHANGE `subtitle` `subtitle` TINYTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL") or error(db_error()); |
||||
|
case false: |
||||
|
// Update version number |
||||
|
file_write($config['has_installed'], VERSION); |
||||
|
|
||||
|
$page['title'] = 'Upgraded'; |
||||
|
$page['body'] = '<p style="text-align:center">Successfully upgraded from ' . $version . ' to <strong>' . VERSION . '</strong>.</p>'; |
||||
|
break; |
||||
|
default: |
||||
|
$page['title'] = 'Unknown version'; |
||||
|
$page['body'] = '<p style="text-align:center">Tinyboard was unable to determine what version is currently installed.</p>'; |
||||
|
break; |
||||
|
case VERSION: |
||||
|
$page['title'] = 'Already installed'; |
||||
|
$page['body'] = '<p style="text-align:center">It appears that Tinyboard is already installed (' . $version . ') and there is nothing to upgrade! Delete <strong>' . $config['has_installed'] . '</strong> to reinstall.</p>'; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
die(Element('page.html', $page)); |
||||
|
} |
||||
|
|
||||
|
if($step == 0) { |
||||
|
// Agreeement |
||||
|
$page['body'] = ' |
||||
|
<textarea style="width:700px;height:370px;margin:auto;display:block;background:white;color:black" disabled>' . htmlentities(file_get_contents('LICENSE.md')) . '</textarea> |
||||
|
<p style="text-align:center"> |
||||
|
<a href="?step=1">I have read and understood the agreement. Proceed to installation.</a> |
||||
|
</p>'; |
||||
|
|
||||
|
echo Element('page.html', $page); |
||||
|
} elseif($step == 1) { |
||||
|
$page['title'] = 'Pre-installation test'; |
||||
|
|
||||
|
$page['body'] = '<table class="test">'; |
||||
|
|
||||
|
function rheader($item) { |
||||
|
global $page, $config; |
||||
|
|
||||
die(Element('page.html', $page)); |
$page['body'] .= '<tr class="h"><th colspan="2">' . $item . '</th></tr>'; |
||||
} |
} |
||||
|
|
||||
if($step == 0) { |
function row($item, $result) { |
||||
// Agreeement |
global $page, $config, $__is_error; |
||||
$page['body'] = ' |
if(!$result) |
||||
<textarea style="width:700px;height:370px;margin:auto;display:block;background:white;color:black" disabled>' . htmlentities(file_get_contents('LICENSE.md')) . '</textarea> |
$__is_error = true; |
||||
<p style="text-align:center"> |
$page['body'] .= '<tr><th>' . $item . '</th><td><img style="width:16px;height:16px" src="' . $config['dir']['static'] . ($result ? 'ok.png' : 'error.png') . '" /></td></tr>'; |
||||
<a href="?step=1">I have read and understood the agreement. Proceed to installation.</a> |
} |
||||
</p>'; |
|
||||
|
|
||||
echo Element('page.html', $page); |
// Required extensions |
||||
} elseif($step == 1) { |
rheader('PHP extensions'); |
||||
$page['title'] = 'Pre-installation test'; |
row('PDO', extension_loaded('pdo')); |
||||
|
row('GD', extension_loaded('gd')); |
||||
|
|
||||
|
// GD tests |
||||
|
rheader('GD tests'); |
||||
|
row('JPEG', function_exists('imagecreatefromjpeg')); |
||||
|
row('PNG', function_exists('imagecreatefrompng')); |
||||
|
row('GIF', function_exists('imagecreatefromgif')); |
||||
|
|
||||
|
// Database drivers |
||||
|
$drivers = PDO::getAvailableDrivers(); |
||||
|
|
||||
|
rheader('PDO drivers <em>(currently installed drivers)</em>'); |
||||
|
foreach($drivers as &$driver) { |
||||
|
row($driver, true); |
||||
|
} |
||||
|
|
||||
|
// Permissions |
||||
|
rheader('File permissions'); |
||||
|
row('<em>root directory</em> (' . getcwd() . ')', is_writable('.')); |
||||
|
|
||||
|
$page['body'] .= '</table> |
||||
|
<p style="text-align:center"> |
||||
|
<a href="?step=2"' . |
||||
|
(isset($__is_error) ? ' onclick="return confirm(\'Are you sure you want to continue when errors exist?\')"' : '') . |
||||
|
'>Continue' . (isset($__is_error) ? ' anyway' : '') . '</a> |
||||
|
</p>'; |
||||
|
|
||||
|
echo Element('page.html', $page); |
||||
|
} elseif($step == 2) { |
||||
|
// Basic config |
||||
|
$page['title'] = 'Configuration'; |
||||
|
|
||||
|
function create_salt() { |
||||
|
return substr(base64_encode(sha1(rand())), 0, rand(25, 31)); |
||||
|
} |
||||
|
|
||||
|
$page['body'] = ' |
||||
|
<form action="?step=3" method="post"> |
||||
|
<fieldset> |
||||
|
<legend>Database</legend> |
||||
|
<label for="db_type">Type:</label> |
||||
|
<select id="db_type" name="db[type]">'; |
||||
|
|
||||
$page['body'] = '<table class="test">'; |
$drivers = PDO::getAvailableDrivers(); |
||||
|
|
||||
function rheader($item) { |
foreach($drivers as &$driver) { |
||||
global $page, $config; |
$driver_txt = $driver; |
||||
|
switch($driver) { |
||||
$page['body'] .= '<tr class="h"><th colspan="2">' . $item . '</th></tr>'; |
case 'cubrid': |
||||
|
$driver_txt = 'Cubrid'; |
||||
|
break; |
||||
|
case 'dblib': |
||||
|
$driver_txt = 'FreeTDS / Microsoft SQL Server / Sybase'; |
||||
|
break; |
||||
|
case 'firebird': |
||||
|
$driver_txt = 'Firebird/Interbase 6'; |
||||
|
break; |
||||
|
case 'ibm': |
||||
|
$driver_txt = 'IBM DB2'; |
||||
|
break; |
||||
|
case 'informix': |
||||
|
$driver_txt = 'IBM Informix Dynamic Server'; |
||||
|
break; |
||||
|
case 'mysql': |
||||
|
$driver_txt = 'MySQL'; |
||||
|
break; |
||||
|
case 'oci': |
||||
|
$driver_txt = 'OCI'; |
||||
|
break; |
||||
|
case 'odbc': |
||||
|
$driver_txt = 'ODBC v3 (IBM DB2, unixODBC)'; |
||||
|
break; |
||||
|
case 'pgsql': |
||||
|
$driver_txt = 'PostgreSQL'; |
||||
|
break; |
||||
|
case 'sqlite': |
||||
|
$driver_txt = 'SQLite 3'; |
||||
|
break; |
||||
|
case 'sqlite2': |
||||
|
$driver_txt = 'SQLite 2'; |
||||
|
break; |
||||
|
} |
||||
|
$page['body'] .= '<option value="' . $driver . '">' . $driver_txt . '</option>'; |
||||
} |
} |
||||
|
|
||||
function row($item, $result) { |
$page['body'] .= ' |
||||
global $page, $config, $__is_error; |
</select> |
||||
if(!$result) |
|
||||
$__is_error = true; |
|
||||
$page['body'] .= '<tr><th>' . $item . '</th><td><img style="width:16px;height:16px" src="' . $config['dir']['static'] . ($result ? 'ok.png' : 'error.png') . '" /></td></tr>'; |
|
||||
} |
|
||||
|
|
||||
|
<label for="db_server">Server:</label> |
||||
|
<input type="text" id="db_server" name="db[server]" value="localhost" /> |
||||
|
|
||||
// Required extensions |
<label for="db_db">Database:</label> |
||||
rheader('PHP extensions'); |
<input type="text" id="db_db" name="db[database]" value="" /> |
||||
row('PDO', extension_loaded('pdo')); |
|
||||
row('GD', extension_loaded('gd')); |
|
||||
|
|
||||
// GD tests |
<label for="db_user">Username:</label> |
||||
rheader('GD tests'); |
<input type="text" id="db_user" name="db[user]" value="" /> |
||||
row('JPEG', function_exists('imagecreatefromjpeg')); |
|
||||
row('PNG', function_exists('imagecreatefrompng')); |
|
||||
row('GIF', function_exists('imagecreatefromgif')); |
|
||||
|
|
||||
// Database drivers |
<label for="db_pass">Password:</label> |
||||
$drivers = PDO::getAvailableDrivers(); |
<input type="password" id="db_pass" name="db[password]" value="" /> |
||||
|
</fieldset> |
||||
|
<p style="text-align:center" class="unimportant">The following is all later configurable. For more options, <a href="http://tinyboard.org/docs/?p=Config">edit your configuration files</a> after installing.</p> |
||||
|
<fieldset> |
||||
|
<legend>Cookies</legend> |
||||
|
<label for="cookies_mod">Moderator cookie:</label> |
||||
|
<input type="text" id="cookies_mod" name="cookies[mod]" value="' . $config['cookies']['mod'] . '" /> |
||||
|
|
||||
rheader('PDO drivers <em>(currently installed drivers)</em>'); |
<label for="cookies_salt">Secure salt:</label> |
||||
foreach($drivers as &$driver) { |
<input type="text" id="cookies_salt" name="cookies[salt]" value="' . create_salt() . '" size="40" /> |
||||
row($driver, true); |
</fieldset> |
||||
} |
|
||||
|
<fieldset> |
||||
|
<legend>Flood control</legend> |
||||
|
<label for="flood_time">Seconds before each post:</label> |
||||
|
<input type="text" id="flood_time" name="flood_time" value="' . $config['flood_time'] . '" /> |
||||
|
|
||||
// Permissions |
<label for="flood_time_ip">Seconds before you can repost something (post the exact same text):</label> |
||||
rheader('File permissions'); |
<input type="text" id="flood_time_ip" name="flood_time_ip" value="' . $config['flood_time_ip'] . '" /> |
||||
row('<em>root directory</em> (' . getcwd() . ')', is_writable('.')); |
|
||||
|
|
||||
$page['body'] .= '</table> |
<label for="flood_time_same">Same as above, but with a different IP address:</label> |
||||
<p style="text-align:center"> |
<input type="text" id="flood_time_same" name="flood_time_same" value="' . $config['flood_time_same'] . '" /> |
||||
<a href="?step=2"' . |
|
||||
(isset($__is_error) ? ' onclick="return confirm(\'Are you sure you want to continue when errors exist?\')"' : '') . |
|
||||
'>Continue' . (isset($__is_error) ? ' anyway' : '') . '</a> |
|
||||
</p>'; |
|
||||
|
|
||||
echo Element('page.html', $page); |
<label for="max_body">Maximum post body length:</label> |
||||
} elseif($step == 2) { |
<input type="text" id="max_body" name="max_body" value="' . $config['max_body'] . '" /> |
||||
// Basic config |
|
||||
$page['title'] = 'Configuration'; |
|
||||
|
|
||||
function create_salt() { |
<label for="reply_limit">Replies in a thread before it can no longer be bumped:</label> |
||||
return substr(base64_encode(sha1(rand())), 0, rand(25, 31)); |
<input type="text" id="reply_limit" name="reply_limit" value="' . $config['reply_limit'] . '" /> |
||||
} |
|
||||
|
|
||||
$page['body'] = ' |
<label for="max_links">Maximum number of links in a single post:</label> |
||||
<form action="?step=3" method="post"> |
<input type="text" id="max_links" name="max_links" value="' . $config['max_links'] . '" /> |
||||
<fieldset> |
</fieldset> |
||||
<legend>Database</legend> |
|
||||
<label for="db_type">Type:</label> |
<fieldset> |
||||
<select id="db_type" name="db[type]">'; |
<legend>Images</legend> |
||||
|
<label for="max_filesize">Maximum image filesize:</label> |
||||
$drivers = PDO::getAvailableDrivers(); |
<input type="text" id="max_filesize" name="max_filesize" value="' . $config['max_filesize'] . '" /> |
||||
|
|
||||
foreach($drivers as &$driver) { |
|
||||
$driver_txt = $driver; |
|
||||
switch($driver) { |
|
||||
case 'cubrid': |
|
||||
$driver_txt = 'Cubrid'; |
|
||||
break; |
|
||||
case 'dblib': |
|
||||
$driver_txt = 'FreeTDS / Microsoft SQL Server / Sybase'; |
|
||||
break; |
|
||||
case 'firebird': |
|
||||
$driver_txt = 'Firebird/Interbase 6'; |
|
||||
break; |
|
||||
case 'ibm': |
|
||||
$driver_txt = 'IBM DB2'; |
|
||||
break; |
|
||||
case 'informix': |
|
||||
$driver_txt = 'IBM Informix Dynamic Server'; |
|
||||
break; |
|
||||
case 'mysql': |
|
||||
$driver_txt = 'MySQL'; |
|
||||
break; |
|
||||
case 'oci': |
|
||||
$driver_txt = 'OCI'; |
|
||||
break; |
|
||||
case 'odbc': |
|
||||
$driver_txt = 'ODBC v3 (IBM DB2, unixODBC)'; |
|
||||
break; |
|
||||
case 'pgsql': |
|
||||
$driver_txt = 'PostgreSQL'; |
|
||||
break; |
|
||||
case 'sqlite': |
|
||||
$driver_txt = 'SQLite 3'; |
|
||||
break; |
|
||||
case 'sqlite2': |
|
||||
$driver_txt = 'SQLite 2'; |
|
||||
break; |
|
||||
} |
|
||||
$page['body'] .= '<option value="' . $driver . '">' . $driver_txt . '</option>'; |
|
||||
} |
|
||||
|
|
||||
$page['body'] .= ' |
|
||||
</select> |
|
||||
|
|
||||
<label for="db_server">Server:</label> |
|
||||
<input type="text" id="db_server" name="db[server]" value="localhost" /> |
|
||||
|
|
||||
<label for="db_db">Database:</label> |
|
||||
<input type="text" id="db_db" name="db[database]" value="" /> |
|
||||
|
|
||||
<label for="db_user">Username:</label> |
|
||||
<input type="text" id="db_user" name="db[user]" value="" /> |
|
||||
|
|
||||
<label for="db_pass">Password:</label> |
|
||||
<input type="password" id="db_pass" name="db[password]" value="" /> |
|
||||
</fieldset> |
|
||||
<p style="text-align:center" class="unimportant">The following is all later configurable. For more options, <a href="http://tinyboard.org/docs/?p=Config">edit your configuration files</a> after installing.</p> |
|
||||
<fieldset> |
|
||||
<legend>Cookies</legend> |
|
||||
<label for="cookies_mod">Moderator cookie:</label> |
|
||||
<input type="text" id="cookies_mod" name="cookies[mod]" value="' . $config['cookies']['mod'] . '" /> |
|
||||
|
|
||||
<label for="cookies_salt">Secure salt:</label> |
|
||||
<input type="text" id="cookies_salt" name="cookies[salt]" value="' . create_salt() . '" size="40" /> |
|
||||
</fieldset> |
|
||||
|
|
||||
<fieldset> |
<label for="thumb_width">Thumbnail width:</label> |
||||
<legend>Flood control</legend> |
<input type="text" id="thumb_width" name="thumb_width" value="' . $config['thumb_width'] . '" /> |
||||
<label for="flood_time">Seconds before each post:</label> |
|
||||
<input type="text" id="flood_time" name="flood_time" value="' . $config['flood_time'] . '" /> |
|
||||
|
|
||||
<label for="flood_time_ip">Seconds before you can repost something (post the exact same text):</label> |
|
||||
<input type="text" id="flood_time_ip" name="flood_time_ip" value="' . $config['flood_time_ip'] . '" /> |
|
||||
|
|
||||
<label for="flood_time_same">Same as above, but with a different IP address:</label> |
|
||||
<input type="text" id="flood_time_same" name="flood_time_same" value="' . $config['flood_time_same'] . '" /> |
|
||||
|
|
||||
<label for="max_body">Maximum post body length:</label> |
|
||||
<input type="text" id="max_body" name="max_body" value="' . $config['max_body'] . '" /> |
|
||||
|
|
||||
<label for="reply_limit">Replies in a thread before it can no longer be bumped:</label> |
|
||||
<input type="text" id="reply_limit" name="reply_limit" value="' . $config['reply_limit'] . '" /> |
|
||||
|
|
||||
<label for="max_links">Maximum number of links in a single post:</label> |
|
||||
<input type="text" id="max_links" name="max_links" value="' . $config['max_links'] . '" /> |
|
||||
</fieldset> |
|
||||
|
|
||||
<fieldset> |
<label for="thumb_height">Thumbnail height:</label> |
||||
<legend>Images</legend> |
<input type="text" id="thumb_height" name="thumb_height" value="' . $config['thumb_height'] . '" /> |
||||
<label for="max_filesize">Maximum image filesize:</label> |
|
||||
<input type="text" id="max_filesize" name="max_filesize" value="' . $config['max_filesize'] . '" /> |
|
||||
|
|
||||
<label for="thumb_width">Thumbnail width:</label> |
|
||||
<input type="text" id="thumb_width" name="thumb_width" value="' . $config['thumb_width'] . '" /> |
|
||||
|
|
||||
<label for="thumb_height">Thumbnail height:</label> |
|
||||
<input type="text" id="thumb_height" name="thumb_height" value="' . $config['thumb_height'] . '" /> |
|
||||
|
|
||||
<label for="max_width">Maximum image width:</label> |
|
||||
<input type="text" id="max_width" name="max_width" value="' . $config['max_width'] . '" /> |
|
||||
|
|
||||
<label for="max_height">Maximum image height:</label> |
|
||||
<input type="text" id="max_height" name="max_height" value="' . $config['max_height'] . '" /> |
|
||||
</fieldset> |
|
||||
|
|
||||
<fieldset> |
<label for="max_width">Maximum image width:</label> |
||||
<legend>Display</legend> |
<input type="text" id="max_width" name="max_width" value="' . $config['max_width'] . '" /> |
||||
<label for="threads_per_page">Threads per page:</label> |
|
||||
<input type="text" id="threads_per_page" name="threads_per_page" value="' . $config['threads_per_page'] . '" /> |
|
||||
|
|
||||
<label for="max_pages">Page limit:</label> |
|
||||
<input type="text" id="max_pages" name="max_pages" value="' . $config['max_pages'] . '" /> |
|
||||
|
|
||||
<label for="threads_preview">Number of replies to show per thread on the index page:</label> |
|
||||
<input type="text" id="threads_preview" name="threads_preview" value="' . $config['threads_preview'] . '" /> |
|
||||
</fieldset> |
|
||||
|
|
||||
<fieldset> |
<label for="max_height">Maximum image height:</label> |
||||
<legend>Directories</legend> |
<input type="text" id="max_height" name="max_height" value="' . $config['max_height'] . '" /> |
||||
<label for="root">Root URI (include trailing slash):</label> |
</fieldset> |
||||
<input type="text" id="root" name="root" value="' . $config['root'] . '" /> |
|
||||
|
<fieldset> |
||||
<label for="dir_img">Image directory:</label> |
<legend>Display</legend> |
||||
<input type="text" id="dir_img" name="dir[img]" value="' . $config['dir']['img'] . '" /> |
<label for="threads_per_page">Threads per page:</label> |
||||
|
<input type="text" id="threads_per_page" name="threads_per_page" value="' . $config['threads_per_page'] . '" /> |
||||
<label for="dir_thumb">Thumbnail directory:</label> |
|
||||
<input type="text" id="dir_thumb" name="dir[thumb]" value="' . $config['dir']['thumb'] . '" /> |
|
||||
|
|
||||
<label for="dir_res">Thread directory:</label> |
|
||||
<input type="text" id="dir_res" name="dir[res]" value="' . $config['dir']['res'] . '" /> |
|
||||
</fieldset> |
|
||||
|
|
||||
<fieldset> |
<label for="max_pages">Page limit:</label> |
||||
<legend>Miscellaneous</legend> |
<input type="text" id="max_pages" name="max_pages" value="' . $config['max_pages'] . '" /> |
||||
<label for="secure_trip_salt">Secure trip (##) salt:</label> |
|
||||
<input type="text" id="secure_trip_salt" name="secure_trip_salt" value="' . create_salt() . '" size="40" /> |
|
||||
</fieldset> |
|
||||
|
|
||||
<p style="text-align:center"> |
<label for="threads_preview">Number of replies to show per thread on the index page:</label> |
||||
<input type="submit" value="Complete installation" /> |
<input type="text" id="threads_preview" name="threads_preview" value="' . $config['threads_preview'] . '" /> |
||||
</p> |
</fieldset> |
||||
</form> |
|
||||
'; |
<fieldset> |
||||
|
<legend>Directories</legend> |
||||
|
<label for="root">Root URI (include trailing slash):</label> |
||||
|
<input type="text" id="root" name="root" value="' . $config['root'] . '" /> |
||||
|
|
||||
|
<label for="dir_img">Image directory:</label> |
||||
|
<input type="text" id="dir_img" name="dir[img]" value="' . $config['dir']['img'] . '" /> |
||||
|
|
||||
echo Element('page.html', $page); |
<label for="dir_thumb">Thumbnail directory:</label> |
||||
} elseif($step == 3) { |
<input type="text" id="dir_thumb" name="dir[thumb]" value="' . $config['dir']['thumb'] . '" /> |
||||
$instance_config = |
|
||||
|
<label for="dir_res">Thread directory:</label> |
||||
|
<input type="text" id="dir_res" name="dir[res]" value="' . $config['dir']['res'] . '" /> |
||||
|
</fieldset> |
||||
|
|
||||
|
<fieldset> |
||||
|
<legend>Miscellaneous</legend> |
||||
|
<label for="secure_trip_salt">Secure trip (##) salt:</label> |
||||
|
<input type="text" id="secure_trip_salt" name="secure_trip_salt" value="' . create_salt() . '" size="40" /> |
||||
|
</fieldset> |
||||
|
|
||||
|
<p style="text-align:center"> |
||||
|
<input type="submit" value="Complete installation" /> |
||||
|
</p> |
||||
|
</form> |
||||
|
'; |
||||
|
|
||||
|
|
||||
|
echo Element('page.html', $page); |
||||
|
} elseif($step == 3) { |
||||
|
$instance_config = |
||||
'<?php |
'<?php |
||||
|
|
||||
/* |
/* |
||||
* Instance Configuration |
* Instance Configuration |
||||
* ---------------------- |
* ---------------------- |
||||
* Edit this file and not config.php for imageboard configuration. |
* Edit this file and not config.php for imageboard configuration. |
||||
* |
* |
||||
* You can copy values from config.php (defaults) and paste them here. |
* You can copy values from config.php (defaults) and paste them here. |
||||
*/ |
*/ |
||||
|
|
||||
'; |
'; |
||||
|
|
||||
function create_config_from_array(&$instance_config, &$array, $prefix = '') { |
function create_config_from_array(&$instance_config, &$array, $prefix = '') { |
||||
foreach($array as $name => $value) { |
foreach($array as $name => $value) { |
||||
if(is_array($value)) { |
if(is_array($value)) { |
||||
$instance_config .= "\n"; |
$instance_config .= "\n"; |
||||
create_config_from_array($instance_config, $value, $prefix . '[\'' . addslashes($name) . '\']'); |
create_config_from_array($instance_config, $value, $prefix . '[\'' . addslashes($name) . '\']'); |
||||
$instance_config .= "\n"; |
$instance_config .= "\n"; |
||||
} else { |
} else { |
||||
$instance_config .= ' $config' . $prefix . '[\'' . addslashes($name) . '\'] = '; |
$instance_config .= ' $config' . $prefix . '[\'' . addslashes($name) . '\'] = '; |
||||
|
|
||||
|
if(is_numeric($value)) |
||||
|
$instance_config .= $value; |
||||
|
else |
||||
|
$instance_config .= "'" . addslashes($value) . "'"; |
||||
|
|
||||
if(is_numeric($value)) |
$instance_config .= ";\n"; |
||||
$instance_config .= $value; |
|
||||
else |
|
||||
$instance_config .= "'" . addslashes($value) . "'"; |
|
||||
|
|
||||
$instance_config .= ";\n"; |
|
||||
} |
|
||||
} |
} |
||||
} |
} |
||||
|
} |
||||
create_config_from_array($instance_config, $_POST); |
|
||||
|
create_config_from_array($instance_config, $_POST); |
||||
$instance_config .= "\n"; |
|
||||
|
$instance_config .= "\n"; |
||||
if(@file_put_contents('inc/instance-config.php', $instance_config)) { |
|
||||
header('Location: ?step=4', true, $config['redirect_http']); |
if(@file_put_contents('inc/instance-config.php', $instance_config)) { |
||||
} else { |
header('Location: ?step=4', true, $config['redirect_http']); |
||||
$page['title'] = 'Manual installation required'; |
} else { |
||||
$page['body'] = ' |
$page['title'] = 'Manual installation required'; |
||||
<p>I couldn\'t write to <strong>inc/instance-config.php</strong> with the new configuration, probably due to a permissions error.</p> |
$page['body'] = ' |
||||
<p>Please complete the installation manually by copying and pasting the following code into the contents of <strong>inc/instance-config.php</strong>:</p> |
<p>I couldn\'t write to <strong>inc/instance-config.php</strong> with the new configuration, probably due to a permissions error.</p> |
||||
<textarea style="width:700px;height:370px;margin:auto;display:block;background:white;color:black">' . htmlentities($instance_config) . '</textarea> |
<p>Please complete the installation manually by copying and pasting the following code into the contents of <strong>inc/instance-config.php</strong>:</p> |
||||
<p style="text-align:center"> |
<textarea style="width:700px;height:370px;margin:auto;display:block;background:white;color:black">' . htmlentities($instance_config) . '</textarea> |
||||
<a href="?step=4">Once complete, click here to complete installation.</a> |
<p style="text-align:center"> |
||||
</p> |
<a href="?step=4">Once complete, click here to complete installation.</a> |
||||
'; |
</p> |
||||
echo Element('page.html', $page); |
'; |
||||
} |
|
||||
} elseif($step == 4) { |
|
||||
// SQL installation |
|
||||
|
|
||||
buildJavascript(); |
|
||||
|
|
||||
$sql = @file_get_contents('install.sql') or error("Couldn't load install.sql."); |
|
||||
|
|
||||
// This code is probably horrible, but what I'm trying |
|
||||
// to do is find all of the SQL queires and put them |
|
||||
// in an array. |
|
||||
preg_match_all("/(^|\n)((SET|CREATE|INSERT).+)\n\n/msU", $sql, $queries); |
|
||||
$queries = $queries[2]; |
|
||||
|
|
||||
$queries[] = Element('posts.sql', Array('board' => 'b')); |
|
||||
|
|
||||
$sql_errors = ''; |
|
||||
foreach($queries as &$query) { |
|
||||
if(!query($query)) |
|
||||
$sql_errors .= '<li>' . db_error() . '</li>'; |
|
||||
} |
|
||||
|
|
||||
$boards = listBoards(); |
|
||||
foreach($boards as &$_board) { |
|
||||
setupBoard($_board); |
|
||||
buildIndex(); |
|
||||
} |
|
||||
|
|
||||
$page['title'] = 'Installation complete'; |
|
||||
$page['body'] = '<p style="text-align:center">Thank you for using Tinyboard. Please remember to report any bugs you discover. <a href="http://tinyboard.org/docs/?p=Config">How do I edit the config files?</a></p>'; |
|
||||
|
|
||||
if(!empty($sql_errors)) { |
|
||||
$page['body'] .= '<div class="ban"><h2>SQL errors</h2><p>SQL errors were encountered when trying to install the database. This may be the result of using a database which is already occupied with a Tinyboard installation; if so, you can probably ignore this.</p><p>The errors encountered were:</p><ul>' . $sql_errors . '</ul><p><a href="?step=5">Ignore errors and complete installation.</a></p></div>'; |
|
||||
} else { |
|
||||
file_write($config['has_installed'], VERSION); |
|
||||
if(!file_unlink(__FILE__)) { |
|
||||
$page['body'] .= '<div class="ban"><h2>Delete install.php!</h2><p>I couldn\'t remove <strong>install.php</strong>. You will have to remove it manually.</p></div>'; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
echo Element('page.html', $page); |
echo Element('page.html', $page); |
||||
} elseif($step == 5) { |
} |
||||
$page['title'] = 'Installation complete'; |
} elseif($step == 4) { |
||||
$page['body'] = '<p style="text-align:center">Thank you for using Tinyboard. Please remember to report any bugs you discover.</p>'; |
// SQL installation |
||||
|
|
||||
|
buildJavascript(); |
||||
|
|
||||
|
$sql = @file_get_contents('install.sql') or error("Couldn't load install.sql."); |
||||
|
|
||||
|
// This code is probably horrible, but what I'm trying |
||||
|
// to do is find all of the SQL queires and put them |
||||
|
// in an array. |
||||
|
preg_match_all("/(^|\n)((SET|CREATE|INSERT).+)\n\n/msU", $sql, $queries); |
||||
|
$queries = $queries[2]; |
||||
|
|
||||
|
$queries[] = Element('posts.sql', Array('board' => 'b')); |
||||
|
|
||||
|
$sql_errors = ''; |
||||
|
foreach($queries as &$query) { |
||||
|
if(!query($query)) |
||||
|
$sql_errors .= '<li>' . db_error() . '</li>'; |
||||
|
} |
||||
|
|
||||
|
$boards = listBoards(); |
||||
|
foreach($boards as &$_board) { |
||||
|
setupBoard($_board); |
||||
|
buildIndex(); |
||||
|
} |
||||
|
|
||||
|
$page['title'] = 'Installation complete'; |
||||
|
$page['body'] = '<p style="text-align:center">Thank you for using Tinyboard. Please remember to report any bugs you discover. <a href="http://tinyboard.org/docs/?p=Config">How do I edit the config files?</a></p>'; |
||||
|
|
||||
|
if(!empty($sql_errors)) { |
||||
|
$page['body'] .= '<div class="ban"><h2>SQL errors</h2><p>SQL errors were encountered when trying to install the database. This may be the result of using a database which is already occupied with a Tinyboard installation; if so, you can probably ignore this.</p><p>The errors encountered were:</p><ul>' . $sql_errors . '</ul><p><a href="?step=5">Ignore errors and complete installation.</a></p></div>'; |
||||
|
} else { |
||||
file_write($config['has_installed'], VERSION); |
file_write($config['has_installed'], VERSION); |
||||
if(!file_unlink(__FILE__)) { |
if(!file_unlink(__FILE__)) { |
||||
$page['body'] .= '<div class="ban"><h2>Delete install.php!</h2><p>I couldn\'t remove <strong>install.php</strong>. You will have to remove it manually.</p></div>'; |
$page['body'] .= '<div class="ban"><h2>Delete install.php!</h2><p>I couldn\'t remove <strong>install.php</strong>. You will have to remove it manually.</p></div>'; |
||||
} |
} |
||||
|
|
||||
echo Element('page.html', $page); |
|
||||
} |
} |
||||
?> |
|
||||
|
echo Element('page.html', $page); |
||||
|
} elseif($step == 5) { |
||||
|
$page['title'] = 'Installation complete'; |
||||
|
$page['body'] = '<p style="text-align:center">Thank you for using Tinyboard. Please remember to report any bugs you discover.</p>'; |
||||
|
|
||||
|
file_write($config['has_installed'], VERSION); |
||||
|
if(!file_unlink(__FILE__)) { |
||||
|
$page['body'] .= '<div class="ban"><h2>Delete install.php!</h2><p>I couldn\'t remove <strong>install.php</strong>. You will have to remove it manually.</p></div>'; |
||||
|
} |
||||
|
|
||||
|
echo Element('page.html', $page); |
||||
|
} |
||||
|
|
||||
|
File diff suppressed because it is too large
File diff suppressed because it is too large
Loading…
Reference in new issue