Michael Save
12 years ago
15 changed files with 6754 additions and 6668 deletions
@ -1,107 +1,111 @@ |
|||
<?php |
|||
if($_SERVER['SCRIPT_FILENAME'] == str_replace('\\', '/', __FILE__)) { |
|||
// You cannot request this file directly. |
|||
header('Location: ../', true, 302); |
|||
exit; |
|||
} |
|||
|
|||
/* |
|||
* Copyright (c) 2010-2012 Tinyboard Development Group |
|||
*/ |
|||
|
|||
if(realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) { |
|||
// You cannot request this file directly. |
|||
exit; |
|||
} |
|||
|
|||
class PreparedQueryDebug { |
|||
protected $query; |
|||
|
|||
class PreparedQueryDebug { |
|||
protected $query; |
|||
public function __construct($query) { |
|||
global $pdo; |
|||
$query = preg_replace("/[\n\t]+/", ' ', $query); |
|||
|
|||
public function __construct($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; |
|||
} |
|||
$this->query = $pdo->prepare($query); |
|||
} |
|||
|
|||
function sql_open() { |
|||
global $pdo, $config; |
|||
if($pdo) return true; |
|||
public function __call($function, $args) { |
|||
global $config, $debug; |
|||
|
|||
$dsn = $config['db']['type'] . ':host=' . $config['db']['server'] . ';dbname=' . $config['db']['database']; |
|||
if(!empty($config['db']['dsn'])) |
|||
$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); |
|||
if($config['debug'] && $function == 'execute') { |
|||
$start = microtime(true); |
|||
} |
|||
} |
|||
|
|||
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; |
|||
$return = call_user_func_array(array($this->query, $function), $args); |
|||
|
|||
sql_open(); |
|||
|
|||
if($config['debug']) { |
|||
$start = microtime(true); |
|||
$query = $pdo->query($query); |
|||
if(!$query) |
|||
return false; |
|||
if($config['debug'] && $function == 'execute') { |
|||
$time = round((microtime(true) - $start) * 1000, 2) . 'ms'; |
|||
|
|||
$debug['sql'][] = Array( |
|||
'query' => $query->queryString, |
|||
'rows' => $query->rowCount(), |
|||
'query' => $this->query->queryString, |
|||
'rows' => $this->query->rowCount(), |
|||
'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) { |
|||
global $pdo; |
|||
if(isset($PDOStatement)) { |
|||
$err = $PDOStatement->errorInfo(); |
|||
return $err[2]; |
|||
} else { |
|||
$err = $pdo->errorInfo(); |
|||
return $err[2]; |
|||
} |
|||
$dsn = $config['db']['type'] . ':host=' . $config['db']['server'] . ';dbname=' . $config['db']['database']; |
|||
if(!empty($config['db']['dsn'])) |
|||
$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 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 |
|||
if($_SERVER['SCRIPT_FILENAME'] == str_replace('\\', '/', __FILE__)) { |
|||
// You cannot request this file directly. |
|||
header('Location: ../', true, 302); |
|||
exit; |
|||
|
|||
/* |
|||
* Copyright (c) 2010-2012 Tinyboard Development Group |
|||
*/ |
|||
|
|||
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); |
|||
|
|||
/* |
|||
Stuff to help with the display. |
|||
*/ |
|||
return $body; |
|||
} |
|||
|
|||
function createBoardlist($mod=false) { |
|||
global $config; |
|||
|
|||
if(!isset($config['boards'])) return Array('top'=>'','bottom'=>''); |
|||
|
|||
/* |
|||
[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]; |
|||
} |
|||
$body = doBoardListPart($config['boards'], $mod?'?/':$config['root']); |
|||
if(!preg_match('/\] $/', $body)) |
|||
$body = '[' . $body . ']'; |
|||
|
|||
function commaize($n) { |
|||
$n = strval($n); |
|||
return (intval($n) < 1000) ? $n : commaize(substr($n, 0, -3)) . ',' . substr($n, -3); |
|||
} |
|||
$body = trim($body); |
|||
|
|||
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; |
|||
} |
|||
return Array( |
|||
'top' => '<div class="boardlist">' . $body . '</div>', |
|||
'bottom' => '<div class="boardlist bottom">' . $body . '</div>' |
|||
); |
|||
} |
|||
|
|||
function error($message, $priority = true) { |
|||
global $board, $mod, $config; |
|||
|
|||
function createBoardlist($mod=false) { |
|||
global $config; |
|||
|
|||
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>' |
|||
); |
|||
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); |
|||
} |
|||
|
|||
function error($message, $priority = true) { |
|||
global $board, $mod, $config; |
|||
|
|||
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>' |
|||
))); |
|||
if(defined('STDIN')) { |
|||
// Running from CLI |
|||
die('Error: ' . $message . "\n"); |
|||
} |
|||
|
|||
function loginForm($error=false, $username=false, $redirect=false) { |
|||
global $config; |
|||
|
|||
die(Element('page.html', Array( |
|||
'index'=>$config['root'], |
|||
'title'=>_('Login'), |
|||
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) { |
|||
global $config; |
|||
|
|||
die(Element('page.html', Array( |
|||
'index'=>$config['root'], |
|||
'title'=>_('Login'), |
|||
'config'=>$config, |
|||
'body'=>Element('login.html', Array( |
|||
'config'=>$config, |
|||
'body'=>Element('login.html', Array( |
|||
'config'=>$config, |
|||
'error'=>$error, |
|||
'username'=>utf8tohtml($username), |
|||
'redirect'=>$redirect |
|||
) |
|||
'error'=>$error, |
|||
'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) { |
|||
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>'; |
|||
return $capcode; |
|||
} |
|||
|
|||
function truncate($body, $url, $max_lines = false, $max_chars = false) { |
|||
global $config; |
|||
|
|||
if($max_lines === false) |
|||
$max_lines = $config['body_truncate']; |
|||
if($max_chars === false) |
|||
$max_chars = $config['body_truncate_char']; |
|||
$original_body = $body; |
|||
|
|||
$lines = substr_count($body, '<br/>'); |
|||
|
|||
// Limit line count |
|||
if($lines > $max_lines) { |
|||
if(preg_match('/(((.*?)<br\/>){' . $max_lines . '})/', $body, $m)) |
|||
$body = $m[0]; |
|||
} |
|||
|
|||
function capcode($cap) { |
|||
global $config; |
|||
|
|||
if(!$cap) |
|||
return false; |
|||
$body = substr($body, 0, $max_chars); |
|||
|
|||
if($body != $original_body) { |
|||
// Remove any corrupt tags at the end |
|||
$body = preg_replace('/<([\w]+)?([^>]*)?$/', '', $body); |
|||
|
|||
$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); |
|||
// Open tags |
|||
if(preg_match_all('/<([\w]+)[^>]*>/', $body, $open_tags)) { |
|||
|
|||
$tags = Array(); |
|||
for($x=0;$x<count($open_tags[0]);$x++) { |
|||
if(!preg_match('/\/(\s+)?>$/', $open_tags[0][$x])) |
|||
$tags[] = $open_tags[1][$x]; |
|||
} |
|||
|
|||
// 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 { |
|||
$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; |
|||
if(!isset($root)) |
|||
$root = &$config['root']; |
|||
|
|||
if($max_lines === false) |
|||
$max_lines = $config['body_truncate']; |
|||
if($max_chars === false) |
|||
$max_chars = $config['body_truncate_char']; |
|||
$original_body = $body; |
|||
$this->id = $id; |
|||
$this->thread = $thread; |
|||
$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->ip = $ip; |
|||
$this->embed = $embed; |
|||
$this->root = $root; |
|||
$this->mod = $mod; |
|||
|
|||
$lines = substr_count($body, '<br/>'); |
|||
|
|||
// Limit line count |
|||
if($lines > $max_lines) { |
|||
if(preg_match('/(((.*?)<br\/>){' . $max_lines . '})/', $body, $m)) |
|||
$body = $m[0]; |
|||
} |
|||
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 $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) { |
|||
// Remove any corrupt tags at the end |
|||
$body = preg_replace('/<([\w]+)?([^>]*)?$/', '', $body); |
|||
$built = ''; |
|||
if($this->mod) { |
|||
// Mod controls (on posts) |
|||
|
|||
// Open tags |
|||
if(preg_match_all('/<([\w]+)[^>]*>/', $body, $open_tags)) { |
|||
|
|||
$tags = Array(); |
|||
for($x=0;$x<count($open_tags[0]);$x++) { |
|||
if(!preg_match('/\/(\s+)?>$/', $open_tags[0][$x])) |
|||
$tags[] = $open_tags[1][$x]; |
|||
} |
|||
|
|||
// 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 { |
|||
// remove broken HTML entity at the end (if existent) |
|||
$body = preg_replace('/&[^;]+$/', '', $body); |
|||
} |
|||
// 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>'; |
|||
|
|||
$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 $body; |
|||
return $built; |
|||
} |
|||
|
|||
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>'; |
|||
public function build($index=false) { |
|||
global $board, $config; |
|||
|
|||
return Element('post_reply.html', Array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index)); |
|||
} |
|||
|
|||
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; |
|||
if(!isset($root)) $root = &$config['root']; |
|||
}; |
|||
|
|||
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; |
|||
$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; |
|||
$this->thread = $thread; |
|||
$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->ip = $ip; |
|||
$this->embed = $embed; |
|||
$this->root = $root; |
|||
$this->mod = $mod; |
|||
// 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); |
|||
|
|||
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 $1href="?/$4', |
|||
$this->body |
|||
); |
|||
} |
|||
public function link($pre = '') { |
|||
global $config, $board; |
|||
// 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'); |
|||
|
|||
return $this->root . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $this->thread) . '#' . $pre . $this->id; |
|||
} |
|||
public function postControls() { |
|||
global $board, $config; |
|||
// 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>'; |
|||
|
|||
$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); |
|||
|
|||
// 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; |
|||
// 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>'; |
|||
|
|||
return Element('post_reply.html', Array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index)); |
|||
} |
|||
}; |
|||
|
|||
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']; |
|||
// 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>'; |
|||
|
|||
$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; |
|||
// 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($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; |
|||
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>'; |
|||
|
|||
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; |
|||
// 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>'; |
|||
|
|||
$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); |
|||
|
|||
// 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; |
|||
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>'; |
|||
|
|||
$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']) { |
|||
cache::set($this->cache_key($index), $built); |
|||
} |
|||
|
|||
return $built; |
|||
if(!empty($built)) |
|||
$built = '<span class="controls op">' . $built . '</span>'; |
|||
} |
|||
function cache_key($index) { |
|||
global $board; |
|||
|
|||
return 'thread_' . ($index ? 'index_' : '') . $board['uri'] . '_' . $this->id; |
|||
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)); |
|||
|
|||
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 |
|||
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; |
|||
public function __construct($src, $format = false) { |
|||
global $config; |
|||
|
|||
$this->src = $src; |
|||
$this->format = $format; |
|||
|
|||
if($config['thumb_method'] == 'imagick') { |
|||
$classname = 'ImageImagick'; |
|||
} elseif($config['thumb_method'] == 'convert') { |
|||
$classname = 'ImageConvert'; |
|||
} else { |
|||
$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']); |
|||
} |
|||
} |
|||
/* |
|||
* Copyright (c) 2010-2012 Tinyboard Development Group |
|||
*/ |
|||
|
|||
if(realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) { |
|||
// You cannot request this file directly. |
|||
exit; |
|||
} |
|||
|
|||
class Image { |
|||
public $src, $format, $image, $size; |
|||
public function __construct($src, $format = false) { |
|||
global $config; |
|||
|
|||
public function resize($extension, $max_width, $max_height) { |
|||
global $config; |
|||
|
|||
if($config['thumb_method'] == 'imagick') { |
|||
$classname = 'ImageImagick'; |
|||
} elseif($config['thumb_method'] == 'convert') { |
|||
$classname = 'ImageConvert'; |
|||
} else { |
|||
$classname = 'Image' . strtoupper($extension); |
|||
if(!class_exists($classname)) { |
|||
error('Unsupported file format: ' . $extension); |
|||
} |
|||
} |
|||
|
|||
$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; |
|||
$this->src = $src; |
|||
$this->format = $format; |
|||
|
|||
if($config['thumb_method'] == 'imagick') { |
|||
$classname = 'ImageImagick'; |
|||
} elseif($config['thumb_method'] == 'convert') { |
|||
$classname = 'ImageConvert'; |
|||
} else { |
|||
$classname = 'Image' . strtoupper($this->format); |
|||
if(!class_exists($classname)) { |
|||
error('Unsupported file format: ' . $this->format); |
|||
} |
|||
|
|||
$thumb->_resize($this->image->image, $width, $height); |
|||
return $thumb; |
|||
} |
|||
|
|||
public function to($dst) { |
|||
$this->image->to($dst); |
|||
$this->image = new $classname($this); |
|||
if(!$this->image->valid()) { |
|||
$this->delete(); |
|||
error($config['error']['invalidimg']); |
|||
} |
|||
|
|||
public function delete() { |
|||
file_unlink($this->src); |
|||
} |
|||
public function destroy() { |
|||
$this->image->_destroy(); |
|||
$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']); |
|||
} |
|||
} |
|||
|
|||
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 resize($extension, $max_width, $max_height) { |
|||
global $config; |
|||
|
|||
if($config['thumb_method'] == 'imagick') { |
|||
$classname = 'ImageImagick'; |
|||
} 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(); |
|||
$this->GD_copyresampled(); |
|||
|
|||
$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; |
|||
} |
|||
|
|||
class ImageBase extends ImageGD { |
|||
public $image, $src, $original, $original_width, $original_height, $width, $height; |
|||
public function valid() { |
|||
return (bool)$this->image; |
|||
} |
|||
public function to($dst) { |
|||
$this->image->to($dst); |
|||
} |
|||
|
|||
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(method_exists($this, 'init')) |
|||
$this->init(); |
|||
|
|||
if($img !== false) { |
|||
$this->src = $img->src; |
|||
$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, '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(); |
|||
if(method_exists($this, 'resize')) |
|||
$this->resize(); |
|||
else |
|||
// use default GD functions |
|||
return imagedestroy($this->image); |
|||
} |
|||
public function _resize($original, $width, $height) { |
|||
$this->original = &$original; |
|||
$this->width = $width; |
|||
$this->height = $height; |
|||
|
|||
if(method_exists($this, 'resize')) |
|||
$this->resize(); |
|||
else |
|||
// use default GD functions |
|||
$this->GD_resize(); |
|||
$this->GD_resize(); |
|||
} |
|||
} |
|||
|
|||
class ImageImagick extends ImageBase { |
|||
public function init() { |
|||
$this->image = new Imagick(); |
|||
$this->image->setBackgroundColor(new ImagickPixel('transparent')); |
|||
} |
|||
public function from() { |
|||
try { |
|||
$this->image->readImage($this->src); |
|||
} catch(ImagickException $e) { |
|||
// invalid image |
|||
$this->image = false; |
|||
} |
|||
} |
|||
|
|||
class ImageImagick extends ImageBase { |
|||
public function init() { |
|||
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') { |
|||
$this->image = new Imagick(); |
|||
$this->image->setBackgroundColor(new ImagickPixel('transparent')); |
|||
} |
|||
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; |
|||
$this->image->setFormat('gif'); |
|||
|
|||
if(preg_match('/\.gif$/i', $this->src) && $config['thumb_ext'] == 'gif') { |
|||
$this->image = new Imagick(); |
|||
$this->image->setFormat('gif'); |
|||
|
|||
$keep_frames = Array(); |
|||
for($i = 0; $i < $this->original->getNumberImages(); $i += floor($this->original->getNumberImages() / $config['thumb_keep_animation_frames'])) |
|||
$keep_frames[] = $i; |
|||
$keep_frames = Array(); |
|||
for($i = 0; $i < $this->original->getNumberImages(); $i += floor($this->original->getNumberImages() / $config['thumb_keep_animation_frames'])) |
|||
$keep_frames[] = $i; |
|||
|
|||
$i = 0; |
|||
$delay = 0; |
|||
foreach($this->original as $frame) { |
|||
$delay += $frame->getImageDelay(); |
|||
|
|||
$i = 0; |
|||
$delay = 0; |
|||
foreach($this->original as $frame) { |
|||
$delay += $frame->getImageDelay(); |
|||
//if($i < $config['thumb_keep_animation_frames']) { |
|||
if(in_array($i, $keep_frames)) { |
|||
// $frame->scaleImage($this->width, $this->height, false); |
|||
$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']) { |
|||
if(in_array($i, $keep_frames)) { |
|||
// $frame->scaleImage($this->width, $this->height, false); |
|||
$frame->sampleImage($this->width, $this->height); |
|||
$frame->setImagePage($this->width, $this->height, 0, 0); |
|||
$frame->setImageDelay($delay); |
|||
$delay = 0; |
|||
|
|||
$this->image->addImage($frame->getImage()); |
|||
} |
|||
$i++; |
|||
} |
|||
} else { |
|||
$this->image = clone $this->original; |
|||
$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; |
|||
|
|||
|
|||
class ImageConvert extends ImageBase { |
|||
public $width, $height, $temp; |
|||
public function init() { |
|||
global $config; |
|||
|
|||
public function init() { |
|||
global $config; |
|||
|
|||
$this->temp = false; |
|||
} |
|||
public function from() { |
|||
$size = trim(shell_exec('identify -format "%w %h" ' . escapeshellarg($this->src . '[0]'))); |
|||
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; |
|||
$this->temp = false; |
|||
} |
|||
public function from() { |
|||
$size = trim(shell_exec('identify -format "%w %h" ' . escapeshellarg($this->src . '[0]'))); |
|||
if(preg_match('/^(\d+) (\d+)$/', $size, $m)) { |
|||
$this->width = $m[1]; |
|||
$this->height = $m[2]; |
|||
|
|||
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!'); |
|||
$this->image = true; |
|||
} else { |
|||
// mark as invalid |
|||
$this->image = false; |
|||
} |
|||
} |
|||
|
|||
class ImagePNG extends ImageBase { |
|||
public function from() { |
|||
$this->image = @imagecreatefrompng($this->src); |
|||
} |
|||
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(); |
|||
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); |
|||
} |
|||
} |
|||
|
|||
class ImageGIF extends ImageBase { |
|||
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 width() { |
|||
return $this->width; |
|||
} |
|||
|
|||
class ImageJPG extends ImageBase { |
|||
public function from() { |
|||
$this->image = @imagecreatefromjpeg($this->src); |
|||
} |
|||
public function to($src) { |
|||
imagejpeg($this->image, $src); |
|||
} |
|||
public function height() { |
|||
return $this->height; |
|||
} |
|||
class ImageJPEG extends ImageJPG { |
|||
public function destroy() { |
|||
@unlink($this->temp); |
|||
$this->temp = false; |
|||
} |
|||
|
|||
class ImageBMP extends ImageBase { |
|||
public function from() { |
|||
$this->image = @imagecreatefrombmp($this->src); |
|||
} |
|||
public function to($src) { |
|||
imagebmp($this->image, $src); |
|||
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)) |
|||
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(); |
|||
if ($BMP['colors'] < 16777216) |
|||
{ |
|||
$PALETTE = unpack('V'.$BMP['colors'], fread($f1,$BMP['colors']*4)); |
|||
} |
|||
class ImagePNG extends ImageBase { |
|||
public function from() { |
|||
$this->image = @imagecreatefrompng($this->src); |
|||
} |
|||
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']); |
|||
$VIDE = chr(0); |
|||
class ImageGIF extends ImageBase { |
|||
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']); |
|||
$P = 0; |
|||
$Y = $BMP['height']-1; |
|||
while ($Y >= 0) |
|||
{ |
|||
$X=0; |
|||
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']; |
|||
} |
|||
$Y--; |
|||
$P+=$BMP['decal']; |
|||
} |
|||
fclose($f1); |
|||
class ImageJPG extends ImageBase { |
|||
public function from() { |
|||
$this->image = @imagecreatefromjpeg($this->src); |
|||
} |
|||
public function to($src) { |
|||
imagejpeg($this->image, $src); |
|||
} |
|||
} |
|||
class ImageJPEG extends ImageJPG { |
|||
} |
|||
|
|||
return $res; |
|||
class ImageBMP extends ImageBase { |
|||
public function from() { |
|||
$this->image = @imagecreatefrombmp($this->src); |
|||
} |
|||
|
|||
function imagebmp(&$img, $filename='') { |
|||
$widthOrig = imagesx($img); |
|||
$widthFloor = ((floor($widthOrig/16))*16); |
|||
$widthCeil = ((ceil($widthOrig/16))*16); |
|||
$height = imagesy($img); |
|||
public function to($src) { |
|||
imagebmp($this->image, $src); |
|||
} |
|||
} |
|||
|
|||
$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) |
|||
/*********************************************/ |
|||
/* Fonction: imagecreatefrombmp */ |
|||
/* Author: DHKold */ |
|||
/* Contact: [email protected] */ |
|||
/* Date: The 15th of June 2005 */ |
|||
/* Version: 2.0B */ |
|||
/*********************************************/ |
|||
|
|||
// is faster than chr() |
|||
$arrChr = array(); |
|||
for($i=0; $i<256; $i++){ |
|||
$arrChr[$i] = chr($i); |
|||
} |
|||
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; |
|||
|
|||
// creates image data |
|||
$bgfillcolor = array('red'=>0, 'green'=>0, 'blue'=>0); |
|||
$PALETTE = array(); |
|||
if ($BMP['colors'] < 16777216) |
|||
{ |
|||
$PALETTE = unpack('V'.$BMP['colors'], fread($f1,$BMP['colors']*4)); |
|||
} |
|||
|
|||
// 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--; |
|||
} |
|||
$IMG = fread($f1,$BMP['size_bitmap']); |
|||
$VIDE = chr(0); |
|||
|
|||
// see imagegif |
|||
if($filename == '') { |
|||
echo $result; |
|||
} else { |
|||
$file = fopen($filename, 'wb'); |
|||
fwrite($file, $result); |
|||
fclose($file); |
|||
} |
|||
$res = imagecreatetruecolor($BMP['width'],$BMP['height']); |
|||
$P = 0; |
|||
$Y = $BMP['height']-1; |
|||
while ($Y >= 0) |
|||
{ |
|||
$X=0; |
|||
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 |
|||
function int_to_dword($n) { |
|||
return chr($n & 255).chr(($n >> 8) & 255).chr(($n >> 16) & 255).chr(($n >> 24) & 255); |
|||
$Y--; |
|||
$P+=$BMP['decal']; |
|||
} |
|||
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 |
|||
if($_SERVER['SCRIPT_FILENAME'] == str_replace('\\', '/', __FILE__)) { |
|||
// You cannot request this file directly. |
|||
header('Location: ../', true, 302); |
|||
exit; |
|||
} |
|||
|
|||
/* |
|||
* Copyright (c) 2010-2012 Tinyboard Development Group |
|||
*/ |
|||
|
|||
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 |
|||
function mkhash($username, $password, $salt = false) { |
|||
global $config; |
|||
|
|||
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; |
|||
} |
|||
if(!$salt) { |
|||
// create some sort of salt for the hash |
|||
$salt = substr(base64_encode(sha1(rand() . time(), true) . $config['cookies']['salt']), 0, 15); |
|||
|
|||
// generate hash (method is not important as long as it's strong) |
|||
$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; |
|||
$generated_salt = true; |
|||
} |
|||
|
|||
function login($username, $password, $makehash=true) { |
|||
global $mod; |
|||
|
|||
// 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; |
|||
} |
|||
// generate hash (method is not important as long as it's strong) |
|||
$hash = substr(base64_encode(md5($username . sha1($username . $password . $salt . ($config['mod']['lock_ip'] ? $_SERVER['REMOTE_ADDR'] : ''), true), true)), 0, 20); |
|||
|
|||
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); |
|||
} |
|||
if(isset($generated_salt)) |
|||
return Array($hash, $salt); |
|||
else |
|||
return $hash; |
|||
} |
|||
|
|||
function login($username, $password, $makehash=true) { |
|||
global $mod; |
|||
|
|||
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); |
|||
// SHA1 password |
|||
if($makehash) { |
|||
$password = sha1($password); |
|||
} |
|||
|
|||
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); |
|||
} |
|||
|
|||
return false; |
|||
$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() { |
|||
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) { |
|||
global $mod, $board, $config; |
|||
$query = prepare("INSERT INTO `modlogs` VALUES (:id, :ip, :board, :time, :text)"); |
|||
$query->bindValue(':id', $mod['id'], PDO::PARAM_INT); |
|||
$query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); |
|||
$query->bindValue(':time', time(), PDO::PARAM_INT); |
|||
$query->bindValue(':text', $action); |
|||
if(isset($_board)) |
|||
$query->bindValue(':board', $_board); |
|||
elseif(isset($board)) |
|||
$query->bindValue(':board', $board['id']); |
|||
else |
|||
$query->bindValue(':board', null, PDO::PARAM_NULL); |
|||
$query->execute() or error(db_error($query)); |
|||
|
|||
if($config['syslog']) |
|||
_syslog(LOG_INFO, '[mod/' . $mod['username'] . ']: ' . $action); |
|||
return false; |
|||
} |
|||
|
|||
function modLog($action, $_board=null) { |
|||
global $mod, $board, $config; |
|||
$query = prepare("INSERT INTO `modlogs` VALUES (:id, :ip, :board, :time, :text)"); |
|||
$query->bindValue(':id', $mod['id'], PDO::PARAM_INT); |
|||
$query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); |
|||
$query->bindValue(':time', time(), PDO::PARAM_INT); |
|||
$query->bindValue(':text', $action); |
|||
if(isset($_board)) |
|||
$query->bindValue(':board', $_board); |
|||
elseif(isset($board)) |
|||
$query->bindValue(':board', $board['id']); |
|||
else |
|||
$query->bindValue(':board', null, PDO::PARAM_NULL); |
|||
$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 |
|||
// 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>'; |
|||
} |
|||
|
|||
if($mod['type'] >= $config['mod']['newboard']) { |
|||
$body .= '<li style="margin-top:15px;"><a href="?/new"><strong>' . _('Create new board') . '</strong></a></li>'; |
|||
} |
|||
return $body; |
|||
if($mod['type'] >= $config['mod']['newboard']) { |
|||
$body .= '<li style="margin-top:15px;"><a href="?/new"><strong>' . _('Create new board') . '</strong></a></li>'; |
|||
} |
|||
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) { |
|||
global $config, $mod; |
|||
|
|||
$boards = listBoards(); |
|||
$__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 .= '<li>' . |
|||
'<input type="radio" name="board_id" id="board_' . $_board['uri'] . '" value="' . $_board['id'] . '">' . |
|||
'<label style="display:inline" for="board_' . $_board['uri'] . '"> ' . |
|||
($_board['uri'] == '*' ? |
|||
'<em>"*"</em>' |
|||
: |
|||
sprintf($config['board_abbreviation'], $_board['uri']) |
|||
) . |
|||
' - ' . $_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>'; |
|||
$boards = listBoards(); |
|||
$__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 .= '<li>' . |
|||
'<input type="radio" name="board_id" id="board_' . $_board['uri'] . '" value="' . $_board['id'] . '">' . |
|||
'<label style="display:inline" for="board_' . $_board['uri'] . '"> ' . |
|||
($_board['uri'] == '*' ? |
|||
'<em>"*"</em>' |
|||
: |
|||
sprintf($config['board_abbreviation'], $_board['uri']) |
|||
) . |
|||
' - ' . $_board['title'] . |
|||
'</label>' . |
|||
'</li>'; |
|||
} |
|||
|
|||
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>' . |
|||
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>' . |
|||
'<td></td>' . |
|||
'<td><input name="new_board" type="submit" value="New Board" /></td>' . |
|||
'</tr>' . |
|||
'</table>' . |
|||
'</form>' . |
|||
'</fieldset>'; |
|||
} |
|||
'<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 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) { |
|||
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)); |
|||
|
|||
//if($config['memcached']['enabled']) { |
|||
// Remove cached ban |
|||
// TODO |
|||
// $memcached->delete("ban_{$id}"); |
|||
//} |
|||
//if($config['memcached']['enabled']) { |
|||
// Remove cached ban |
|||
// TODO |
|||
// $memcached->delete("ban_{$id}"); |
|||
//} |
|||
} |
|||
|
|||
|
|||
// Validate session |
|||
|
|||
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 |
|||
|
|||
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 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']) |
|||
); |
|||
// 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']) |
|||
); |
|||
} |
|||
|
|||
|
@ -1,57 +1,67 @@ |
|||
<?php |
|||
class Remote { |
|||
public function __construct($config) { |
|||
foreach($config as $name => $value) { |
|||
$this->{$name} = $value; |
|||
} |
|||
|
|||
$methods = Array(); |
|||
|
|||
if(!isset($this->auth['method'])) |
|||
error('Unspecified authentication method.'); |
|||
|
|||
// Connect |
|||
$this->connection = ssh2_connect($this->host, isset($this->port) ? $this->port : 22, $methods); |
|||
|
|||
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'] . '".'); |
|||
} |
|||
|
|||
|
|||
/* |
|||
* Copyright (c) 2010-2012 Tinyboard Development Group |
|||
*/ |
|||
|
|||
if(realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) { |
|||
// You cannot request this file directly. |
|||
exit; |
|||
} |
|||
|
|||
class Remote { |
|||
public function __construct($config) { |
|||
foreach($config as $name => $value) { |
|||
$this->{$name} = $value; |
|||
} |
|||
|
|||
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.'); |
|||
} |
|||
$methods = Array(); |
|||
|
|||
if(!isset($this->auth['method'])) |
|||
error('Unspecified authentication method.'); |
|||
|
|||
// Connect |
|||
$this->connection = ssh2_connect($this->host, isset($this->port) ? $this->port : 22, $methods); |
|||
|
|||
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) { |
|||
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 |
|||
if($_SERVER['SCRIPT_FILENAME'] == str_replace('\\', '/', __FILE__)) { |
|||
// You cannot request this file directly. |
|||
header('Location: ../', true, 302); |
|||
exit; |
|||
} |
|||
|
|||
/* |
|||
* Copyright (c) 2010-2012 Tinyboard Development Group |
|||
*/ |
|||
|
|||
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'; |
|||
Twig_Autoloader::register(); |
|||
|
|||
|
|||
Twig_Autoloader::autoload('Twig_Extensions_Node_Trans'); |
|||
Twig_Autoloader::autoload('Twig_Extensions_TokenParser_Trans'); |
|||
Twig_Autoloader::autoload('Twig_Extensions_Extension_I18n'); |
|||
Twig_Autoloader::autoload('Twig_Extensions_Extension_Tinyboard'); |
|||
|
|||
$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) { |
|||
global $config, $debug, $loader; |
|||
|
|||
if(function_exists('create_pm_header') && ((isset($options['mod']) && $options['mod']) || isset($options['__mod']))) { |
|||
$options['pm'] = create_pm_header(); |
|||
if(!$twig) |
|||
load_twig(); |
|||
|
|||
if(function_exists('create_pm_header') && ((isset($options['mod']) && $options['mod']) || isset($options['__mod']))) { |
|||
$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(isset($debug['start'])) { |
|||
$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>'; |
|||
if($config['minify_html'] && preg_match('/\.html$/', $templateFile)) { |
|||
$body = trim(preg_replace("/[\t\r\n]/", '', $body)); |
|||
} |
|||
|
|||
$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()); |
|||
|
|||
// 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']}'!"); |
|||
} |
|||
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 |
|||
// Installation/upgrade file |
|||
define('VERSION', 'v0.9.6-dev-1'); |
|||
|
|||
require 'inc/functions.php'; |
|||
require 'inc/display.php'; |
|||
require 'inc/template.php'; |
|||
require 'inc/database.php'; |
|||
require 'inc/user.php'; |
|||
$step = isset($_GET['step']) ? round($_GET['step']) : 0; |
|||
$page = Array( |
|||
'config' => $config, |
|||
'title' => 'Install', |
|||
'body' => '', |
|||
'nojavascript' => true |
|||
); |
|||
|
|||
// this breaks the dispaly of licenses if enabled |
|||
$config['minify_html'] = false; |
|||
|
|||
if(file_exists($config['has_installed'])) { |
|||
|
|||
// Check the version number |
|||
$version = trim(file_get_contents($config['has_installed'])); |
|||
if(empty($version)) |
|||
$version = 'v0.9.1'; |
|||
|
|||
$boards = listBoards(); |
|||
|
|||
switch($version) { |
|||
case 'v0.9': |
|||
case 'v0.9.1': |
|||
// Upgrade to v0.9.2-dev |
|||
|
|||
foreach($boards as &$_board) { |
|||
// 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']}"; |
|||
} |
|||
|
|||
// Installation/upgrade file |
|||
define('VERSION', 'v0.9.6-dev-1'); |
|||
|
|||
require 'inc/functions.php'; |
|||
|
|||
$step = isset($_GET['step']) ? round($_GET['step']) : 0; |
|||
$page = Array( |
|||
'config' => $config, |
|||
'title' => 'Install', |
|||
'body' => '', |
|||
'nojavascript' => true |
|||
); |
|||
|
|||
// this breaks the dispaly of licenses if enabled |
|||
$config['minify_html'] = false; |
|||
|
|||
if(file_exists($config['has_installed'])) { |
|||
|
|||
// Check the version number |
|||
$version = trim(file_get_contents($config['has_installed'])); |
|||
if(empty($version)) |
|||
$version = 'v0.9.1'; |
|||
|
|||
$boards = listBoards(); |
|||
|
|||
switch($version) { |
|||
case 'v0.9': |
|||
case 'v0.9.1': |
|||
// Upgrade to v0.9.2-dev |
|||
|
|||
foreach($boards as &$_board) { |
|||
// Add `capcode` field after `trip` |
|||
query(sprintf("ALTER TABLE `posts_%s` ADD `capcode` VARCHAR( 50 ) NULL AFTER `trip`", $_board['uri'])) or error(db_error()); |
|||
|
|||
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()); |
|||
// 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) { |
|||
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()); |
|||
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); |
|||
file_write($config['has_installed'], 'v0.9.4-dev-2'); |
|||
|
|||
$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; |
|||
} |
|||
} |
|||
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; |
|||
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) { |
|||
// 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'; |
|||
function row($item, $result) { |
|||
global $page, $config, $__is_error; |
|||
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>'; |
|||
} |
|||
|
|||
|
|||
// Required extensions |
|||
rheader('PHP extensions'); |
|||
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) { |
|||
global $page, $config; |
|||
|
|||
$page['body'] .= '<tr class="h"><th colspan="2">' . $item . '</th></tr>'; |
|||
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>'; |
|||
} |
|||
|
|||
function row($item, $result) { |
|||
global $page, $config, $__is_error; |
|||
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>'; |
|||
} |
|||
$page['body'] .= ' |
|||
</select> |
|||
|
|||
<label for="db_server">Server:</label> |
|||
<input type="text" id="db_server" name="db[server]" value="localhost" /> |
|||
|
|||
// Required extensions |
|||
rheader('PHP extensions'); |
|||
row('PDO', extension_loaded('pdo')); |
|||
row('GD', extension_loaded('gd')); |
|||
<label for="db_db">Database:</label> |
|||
<input type="text" id="db_db" name="db[database]" value="" /> |
|||
|
|||
// GD tests |
|||
rheader('GD tests'); |
|||
row('JPEG', function_exists('imagecreatefromjpeg')); |
|||
row('PNG', function_exists('imagecreatefrompng')); |
|||
row('GIF', function_exists('imagecreatefromgif')); |
|||
<label for="db_user">Username:</label> |
|||
<input type="text" id="db_user" name="db[user]" value="" /> |
|||
|
|||
// Database drivers |
|||
$drivers = PDO::getAvailableDrivers(); |
|||
<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'] . '" /> |
|||
|
|||
rheader('PDO drivers <em>(currently installed drivers)</em>'); |
|||
foreach($drivers as &$driver) { |
|||
row($driver, true); |
|||
} |
|||
<label for="cookies_salt">Secure salt:</label> |
|||
<input type="text" id="cookies_salt" name="cookies[salt]" value="' . create_salt() . '" size="40" /> |
|||
</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 |
|||
rheader('File permissions'); |
|||
row('<em>root directory</em> (' . getcwd() . ')', is_writable('.')); |
|||
<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'] . '" /> |
|||
|
|||
$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>'; |
|||
<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'] . '" /> |
|||
|
|||
echo Element('page.html', $page); |
|||
} elseif($step == 2) { |
|||
// Basic config |
|||
$page['title'] = 'Configuration'; |
|||
<label for="max_body">Maximum post body length:</label> |
|||
<input type="text" id="max_body" name="max_body" value="' . $config['max_body'] . '" /> |
|||
|
|||
function create_salt() { |
|||
return substr(base64_encode(sha1(rand())), 0, rand(25, 31)); |
|||
} |
|||
<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'] . '" /> |
|||
|
|||
$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]">'; |
|||
|
|||
$drivers = PDO::getAvailableDrivers(); |
|||
|
|||
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> |
|||
<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> |
|||
<legend>Images</legend> |
|||
<label for="max_filesize">Maximum image filesize:</label> |
|||
<input type="text" id="max_filesize" name="max_filesize" value="' . $config['max_filesize'] . '" /> |
|||
|
|||
<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'] . '" /> |
|||
|
|||
<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> |
|||
<label for="thumb_width">Thumbnail width:</label> |
|||
<input type="text" id="thumb_width" name="thumb_width" value="' . $config['thumb_width'] . '" /> |
|||
|
|||
<fieldset> |
|||
<legend>Images</legend> |
|||
<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> |
|||
<label for="thumb_height">Thumbnail height:</label> |
|||
<input type="text" id="thumb_height" name="thumb_height" value="' . $config['thumb_height'] . '" /> |
|||
|
|||
<fieldset> |
|||
<legend>Display</legend> |
|||
<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> |
|||
<label for="max_width">Maximum image width:</label> |
|||
<input type="text" id="max_width" name="max_width" value="' . $config['max_width'] . '" /> |
|||
|
|||
<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'] . '" /> |
|||
|
|||
<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> |
|||
<label for="max_height">Maximum image height:</label> |
|||
<input type="text" id="max_height" name="max_height" value="' . $config['max_height'] . '" /> |
|||
</fieldset> |
|||
|
|||
<fieldset> |
|||
<legend>Display</legend> |
|||
<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'] . '" /> |
|||
|
|||
<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> |
|||
<label for="max_pages">Page limit:</label> |
|||
<input type="text" id="max_pages" name="max_pages" value="' . $config['max_pages'] . '" /> |
|||
|
|||
<p style="text-align:center"> |
|||
<input type="submit" value="Complete installation" /> |
|||
</p> |
|||
</form> |
|||
'; |
|||
<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> |
|||
<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); |
|||
} elseif($step == 3) { |
|||
$instance_config = |
|||
<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> |
|||
<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 |
|||
|
|||
/* |
|||
* Instance Configuration |
|||
* ---------------------- |
|||
* Edit this file and not config.php for imageboard configuration. |
|||
* |
|||
* You can copy values from config.php (defaults) and paste them here. |
|||
*/ |
|||
* Instance Configuration |
|||
* ---------------------- |
|||
* Edit this file and not config.php for imageboard configuration. |
|||
* |
|||
* You can copy values from config.php (defaults) and paste them here. |
|||
*/ |
|||
|
|||
'; |
|||
|
|||
function create_config_from_array(&$instance_config, &$array, $prefix = '') { |
|||
foreach($array as $name => $value) { |
|||
if(is_array($value)) { |
|||
$instance_config .= "\n"; |
|||
create_config_from_array($instance_config, $value, $prefix . '[\'' . addslashes($name) . '\']'); |
|||
$instance_config .= "\n"; |
|||
} else { |
|||
$instance_config .= ' $config' . $prefix . '[\'' . addslashes($name) . '\'] = '; |
|||
|
|||
function create_config_from_array(&$instance_config, &$array, $prefix = '') { |
|||
foreach($array as $name => $value) { |
|||
if(is_array($value)) { |
|||
$instance_config .= "\n"; |
|||
create_config_from_array($instance_config, $value, $prefix . '[\'' . addslashes($name) . '\']'); |
|||
$instance_config .= "\n"; |
|||
} else { |
|||
$instance_config .= ' $config' . $prefix . '[\'' . addslashes($name) . '\'] = '; |
|||
|
|||
if(is_numeric($value)) |
|||
$instance_config .= $value; |
|||
else |
|||
$instance_config .= "'" . addslashes($value) . "'"; |
|||
|
|||
if(is_numeric($value)) |
|||
$instance_config .= $value; |
|||
else |
|||
$instance_config .= "'" . addslashes($value) . "'"; |
|||
|
|||
$instance_config .= ";\n"; |
|||
} |
|||
$instance_config .= ";\n"; |
|||
} |
|||
} |
|||
|
|||
create_config_from_array($instance_config, $_POST); |
|||
|
|||
$instance_config .= "\n"; |
|||
|
|||
if(@file_put_contents('inc/instance-config.php', $instance_config)) { |
|||
header('Location: ?step=4', true, $config['redirect_http']); |
|||
} else { |
|||
$page['title'] = 'Manual installation required'; |
|||
$page['body'] = ' |
|||
<p>I couldn\'t write to <strong>inc/instance-config.php</strong> with the new configuration, probably due to a permissions error.</p> |
|||
<p>Please complete the installation manually by copying and pasting the following code into the contents of <strong>inc/instance-config.php</strong>:</p> |
|||
<textarea style="width:700px;height:370px;margin:auto;display:block;background:white;color:black">' . htmlentities($instance_config) . '</textarea> |
|||
<p style="text-align:center"> |
|||
<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>'; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
create_config_from_array($instance_config, $_POST); |
|||
|
|||
$instance_config .= "\n"; |
|||
|
|||
if(@file_put_contents('inc/instance-config.php', $instance_config)) { |
|||
header('Location: ?step=4', true, $config['redirect_http']); |
|||
} else { |
|||
$page['title'] = 'Manual installation required'; |
|||
$page['body'] = ' |
|||
<p>I couldn\'t write to <strong>inc/instance-config.php</strong> with the new configuration, probably due to a permissions error.</p> |
|||
<p>Please complete the installation manually by copying and pasting the following code into the contents of <strong>inc/instance-config.php</strong>:</p> |
|||
<textarea style="width:700px;height:370px;margin:auto;display:block;background:white;color:black">' . htmlentities($instance_config) . '</textarea> |
|||
<p style="text-align:center"> |
|||
<a href="?step=4">Once complete, click here to complete installation.</a> |
|||
</p> |
|||
'; |
|||
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>'; |
|||
|
|||
} |
|||
} 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'; |
|||
$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