2010-11-02 11:57:33 +01:00
< ? php
2012-04-11 18:49:22 +02:00
/*
2013-01-20 11:23:46 +01:00
* Copyright ( c ) 2010 - 2013 Tinyboard Development Group
2012-04-11 18:49:22 +02:00
*/
2012-04-12 16:18:19 +02:00
if ( realpath ( $_SERVER [ 'SCRIPT_FILENAME' ]) == str_replace ( '\\' , '/' , __FILE__ )) {
2012-04-11 18:49:22 +02:00
// You cannot request this file directly.
exit ;
}
/*
joaoptm78 @ gmail . com
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 ];
}
2013-08-18 04:41:40 +02:00
function doBoardListPart ( $list , $root , & $boards ) {
2012-04-11 18:49:22 +02:00
global $config ;
$body = '' ;
2013-08-18 04:41:40 +02:00
foreach ( $list as $key => $board ) {
2012-04-12 16:18:19 +02:00
if ( is_array ( $board ))
2013-08-18 04:41:40 +02:00
$body .= ' <span class="sub" data-description="' . $key . '">[' . doBoardListPart ( $board , $root , $boards ) . ']</span> ' ;
2012-04-11 18:49:22 +02:00
else {
2013-08-18 04:41:40 +02:00
if ( gettype ( $key ) == 'string' ) {
2012-04-11 18:49:22 +02:00
$body .= ' <a href="' . $board . '">' . $key . '</a> /' ;
2013-08-18 04:41:40 +02:00
} else {
$title = '' ;
if ( isset ( $boards [ $board ])) {
$title = ' title="' . $boards [ $board ] . '"' ;
}
$body .= ' <a href="' . $root . $board . '/' . $config [ 'file_index' ] . '"' . $title . '>' . $board . '</a> /' ;
2012-04-11 18:49:22 +02:00
}
}
2011-04-13 14:21:07 +02:00
}
2012-04-11 18:49:22 +02:00
$body = preg_replace ( '/\/$/' , '' , $body );
2011-04-13 14:21:07 +02:00
2012-04-11 18:49:22 +02:00
return $body ;
}
function createBoardlist ( $mod = false ) {
global $config ;
2010-11-02 11:57:33 +01:00
2012-08-27 13:50:15 +02:00
if ( ! isset ( $config [ 'boards' ])) return array ( 'top' => '' , 'bottom' => '' );
2010-11-02 11:57:33 +01:00
2013-08-18 04:41:40 +02:00
$xboards = listBoards ();
$boards = array ();
foreach ( $xboards as $val ) {
$boards [ $val [ 'uri' ]] = $val [ 'title' ];
}
$body = doBoardListPart ( $config [ 'boards' ], $mod ? '?/' : $config [ 'root' ], $boards );
2013-08-11 15:50:33 +02:00
2013-08-11 13:06:13 +02:00
if ( $config [ 'boardlist_wrap_bracket' ] && ! preg_match ( '/\] $/' , $body ))
2012-04-11 18:49:22 +02:00
$body = '[' . $body . ']' ;
2010-11-02 11:57:33 +01:00
2012-04-11 18:49:22 +02:00
$body = trim ( $body );
2013-12-28 00:53:42 +01:00
// Message compact-boardlist.js faster, so that page looks less ugly during loading
$top = " <script type='text/javascript'>if (typeof do_boardlist != 'undefined') do_boardlist();</script> " ;
2011-02-19 10:16:13 +01:00
2012-08-27 13:50:15 +02:00
return array (
2013-12-28 00:53:42 +01:00
'top' => '<div class="boardlist">' . $body . '</div>' . $top ,
2012-04-11 18:49:22 +02:00
'bottom' => '<div class="boardlist bottom">' . $body . '</div>'
);
}
2013-08-03 06:22:28 +02:00
function error ( $message , $priority = true , $debug_stuff = false ) {
2013-08-03 08:01:52 +02:00
global $board , $mod , $config , $db_error ;
2011-02-19 10:16:13 +01:00
2012-04-12 16:18:19 +02:00
if ( $config [ 'syslog' ] && $priority !== false ) {
2012-04-11 18:49:22 +02:00
// Use LOG_NOTICE instead of LOG_ERR or LOG_WARNING because most error message are not significant.
_syslog ( $priority !== true ? $priority : LOG_NOTICE , $message );
2011-02-19 10:16:13 +01:00
}
2011-11-18 13:39:13 +01:00
2012-04-12 16:18:19 +02:00
if ( defined ( 'STDIN' )) {
2012-04-11 18:49:22 +02:00
// Running from CLI
die ( 'Error: ' . $message . " \n " );
2010-11-02 11:57:33 +01:00
}
2013-08-04 04:14:25 +02:00
2013-08-03 08:01:52 +02:00
if ( $config [ 'debug' ] && isset ( $db_error )) {
$debug_stuff = array_combine ( array ( 'SQLSTATE' , 'Error code' , 'Error message' ), $db_error );
}
2013-08-17 21:08:54 +02:00
2014-04-20 23:16:15 +02:00
if ( $config [ 'debug' ]) {
$debug_stuff [ 'backtrace' ] = debug_backtrace ();
}
2013-08-17 21:08:54 +02:00
// Return the bad request header, necessary for AJAX posts
2013-12-23 18:54:24 +01:00
// czaks: is it really so? the ajax errors only work when this is commented out
// better yet use it when ajax is disabled
if ( ! isset ( $_POST [ 'json_response' ])) {
header ( $_SERVER [ 'SERVER_PROTOCOL' ] . ' 400 Bad Request' );
}
2013-08-03 08:01:52 +02:00
2013-09-15 06:03:27 +02:00
// Is there a reason to disable this?
if ( isset ( $_POST [ 'json_response' ])) {
header ( 'Content-Type: text/json; charset=utf-8' );
die ( json_encode ( array (
'error' => $message
)));
}
2012-08-27 13:50:15 +02:00
die ( Element ( 'page.html' , array (
2013-08-03 06:22:28 +02:00
'config' => $config ,
'title' => _ ( 'Error' ),
'subtitle' => _ ( 'An error has occured.' ),
'body' => Element ( 'error.html' , array (
'config' => $config ,
'message' => $message ,
'mod' => $mod ,
'board' => isset ( $board ) ? $board : false ,
'debug' => is_array ( $debug_stuff ) ? str_replace ( " \n " , ' ' , utf8tohtml ( print_r ( $debug_stuff , true ))) : utf8tohtml ( $debug_stuff )
))
2012-04-11 18:49:22 +02:00
)));
}
function loginForm ( $error = false , $username = false , $redirect = false ) {
global $config ;
2012-08-27 07:19:05 +02:00
die ( Element ( 'page.html' , array (
'index' => $config [ 'root' ],
'title' => _ ( 'Login' ),
'config' => $config ,
'body' => Element ( 'login.html' , array (
2011-03-26 09:11:48 +01:00
'config' => $config ,
2012-04-11 18:49:22 +02:00
'error' => $error ,
'username' => utf8tohtml ( $username ),
'redirect' => $redirect
2010-12-01 11:24:14 +01:00
)
2012-04-11 18:49:22 +02:00
)
)));
}
function pm_snippet ( $body , $len = null ) {
global $config ;
2012-04-12 16:18:19 +02:00
if ( ! isset ( $len ))
2012-04-11 18:49:22 +02:00
$len = & $config [ 'mod' ][ 'snippet_length' ];
// Replace line breaks with some whitespace
2013-08-31 05:26:53 +02:00
$body = preg_replace ( '@<br/?>@i' , ' ' , $body );
2012-04-11 18:49:22 +02:00
// 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 );
2013-03-01 01:42:38 +01:00
$body = mb_substr ( $body , 0 , $len );
2012-04-11 18:49:22 +02:00
// Re-escape the characters.
return '<em>' . utf8tohtml ( $body ) . ( $strlen > $len ? '…' : '' ) . '</em>' ;
}
function capcode ( $cap ) {
global $config ;
2012-04-12 16:18:19 +02:00
if ( ! $cap )
2012-04-11 18:49:22 +02:00
return false ;
2012-08-27 13:50:15 +02:00
$capcode = array ();
2012-04-12 16:18:19 +02:00
if ( isset ( $config [ 'custom_capcode' ][ $cap ])) {
if ( is_array ( $config [ 'custom_capcode' ][ $cap ])) {
2012-04-11 18:49:22 +02:00
$capcode [ 'cap' ] = sprintf ( $config [ 'custom_capcode' ][ $cap ][ 0 ], $cap );
2012-04-12 16:18:19 +02:00
if ( isset ( $config [ 'custom_capcode' ][ $cap ][ 1 ]))
2012-04-11 18:49:22 +02:00
$capcode [ 'name' ] = $config [ 'custom_capcode' ][ $cap ][ 1 ];
2012-04-12 16:18:19 +02:00
if ( isset ( $config [ 'custom_capcode' ][ $cap ][ 2 ]))
2012-04-11 18:49:22 +02:00
$capcode [ 'trip' ] = $config [ 'custom_capcode' ][ $cap ][ 2 ];
} else {
$capcode [ 'cap' ] = sprintf ( $config [ 'custom_capcode' ][ $cap ], $cap );
}
} else {
$capcode [ 'cap' ] = sprintf ( $config [ 'capcode' ], $cap );
2010-12-01 11:24:14 +01:00
}
2012-04-11 18:49:22 +02:00
return $capcode ;
}
function truncate ( $body , $url , $max_lines = false , $max_chars = false ) {
global $config ;
2012-04-12 16:18:19 +02:00
if ( $max_lines === false )
2012-04-11 18:49:22 +02:00
$max_lines = $config [ 'body_truncate' ];
2012-04-12 16:18:19 +02:00
if ( $max_chars === false )
2012-04-11 18:49:22 +02:00
$max_chars = $config [ 'body_truncate_char' ];
2013-01-15 02:11:55 +01:00
// We don't want to risk truncating in the middle of an HTML comment.
// It's easiest just to remove them all first.
$body = preg_replace ( '/<!--.*?-->/s' , '' , $body );
2012-04-11 18:49:22 +02:00
$original_body = $body ;
$lines = substr_count ( $body , '<br/>' );
// Limit line count
2012-04-12 16:18:19 +02:00
if ( $lines > $max_lines ) {
if ( preg_match ( '/(((.*?)<br\/>){' . $max_lines . '})/' , $body , $m ))
2012-04-11 18:49:22 +02:00
$body = $m [ 0 ];
2011-04-12 10:02:20 +02:00
}
2013-01-19 01:10:14 +01:00
$body = mb_substr ( $body , 0 , $max_chars );
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( $body != $original_body ) {
2012-04-11 18:49:22 +02:00
// Remove any corrupt tags at the end
$body = preg_replace ( '/<([\w]+)?([^>]*)?$/' , '' , $body );
2011-12-05 00:33:31 +01:00
2012-04-11 18:49:22 +02:00
// Open tags
2012-04-12 16:18:19 +02:00
if ( preg_match_all ( '/<([\w]+)[^>]*>/' , $body , $open_tags )) {
2012-04-11 18:49:22 +02:00
2012-08-27 13:50:15 +02:00
$tags = array ();
2012-04-12 16:18:19 +02:00
for ( $x = 0 ; $x < count ( $open_tags [ 0 ]); $x ++ ) {
if ( ! preg_match ( '/\/(\s+)?>$/' , $open_tags [ 0 ][ $x ]))
2012-04-11 18:49:22 +02:00
$tags [] = $open_tags [ 1 ][ $x ];
}
// List successfully closed tags
2012-04-12 16:18:19 +02:00
if ( preg_match_all ( '/(<\/([\w]+))>/' , $body , $closed_tags )) {
for ( $x = 0 ; $x < count ( $closed_tags [ 0 ]); $x ++ ) {
2012-04-11 18:49:22 +02:00
unset ( $tags [ array_search ( $closed_tags [ 2 ][ $x ], $tags )]);
}
}
// remove broken HTML entity at the end (if existent)
$body = preg_replace ( '/&[^;]+$/' , '' , $body );
2012-08-16 16:05:19 +02:00
$tags_no_close_needed = array ( " colgroup " , " dd " , " dt " , " li " , " optgroup " , " option " , " p " , " tbody " , " td " , " tfoot " , " th " , " thead " , " tr " , " br " , " img " );
2012-04-11 18:49:22 +02:00
// Close any open tags
2012-04-12 16:18:19 +02:00
foreach ( $tags as & $tag ) {
2012-08-16 16:05:19 +02:00
if ( ! in_array ( $tag , $tags_no_close_needed ))
$body .= " </ { $tag } > " ;
2011-12-05 00:33:31 +01:00
}
} else {
2012-04-11 18:49:22 +02:00
// remove broken HTML entity at the end (if existent)
2013-03-17 20:14:30 +01:00
$body = preg_replace ( '/&[^;]*$/' , '' , $body );
2011-04-12 13:08:54 +02:00
}
2013-08-01 07:56:04 +02:00
$body .= '<span class="toolong">' . sprintf ( _ ( 'Post too long. Click <a href="%s">here</a> to view the full text.' ), $url ) . '</span>' ;
2011-04-12 13:08:54 +02:00
}
2012-04-11 18:49:22 +02:00
return $body ;
}
2013-08-19 15:47:56 +02:00
function bidi_cleanup ( $data ) {
// Closes all embedded RTL and LTR unicode formatting blocks in a string so that
2013-08-18 21:19:54 +02:00
// it can be used inside another without controlling its direction.
2013-04-02 11:28:04 +02:00
2013-08-19 15:47:56 +02:00
$explicits = '\xE2\x80\xAA|\xE2\x80\xAB|\xE2\x80\xAD|\xE2\x80\xAE' ;
$pdf = '\xE2\x80\xAC' ;
preg_match_all ( " ! $explicits ! " , $data , $m1 , PREG_OFFSET_CAPTURE | PREG_SET_ORDER );
preg_match_all ( " ! $pdf ! " , $data , $m2 , PREG_OFFSET_CAPTURE | PREG_SET_ORDER );
if ( count ( $m1 ) || count ( $m2 )){
$p = array ();
foreach ( $m1 as $m ){ $p [ $m [ 0 ][ 1 ]] = 'push' ; }
foreach ( $m2 as $m ){ $p [ $m [ 0 ][ 1 ]] = 'pop' ; }
ksort ( $p );
$offset = 0 ;
$stack = 0 ;
foreach ( $p as $pos => $type ){
if ( $type == 'push' ){
$stack ++ ;
} else {
if ( $stack ){
$stack -- ;
} else {
# we have a pop without a push - remove it
$data = substr ( $data , 0 , $pos - $offset )
. substr ( $data , $pos + 3 - $offset );
$offset += 3 ;
}
}
}
# now add some pops if your stack is bigger than 0
for ( $i = 0 ; $i < $stack ; $i ++ ){
$data .= " \xE2 \x80 \xAC " ;
}
return $data ;
}
return $data ;
2013-04-02 11:28:04 +02:00
}
2012-08-27 07:19:05 +02:00
function secure_link_confirm ( $text , $title , $confirm_message , $href ) {
global $config ;
2013-07-31 08:08:55 +02:00
return '<a onclick="if (event.which==2) return true;if (confirm(\'' . htmlentities ( addslashes ( $confirm_message )) . '\')) document.location=\'?/' . htmlspecialchars ( addslashes ( $href . '/' . make_secure_link_token ( $href ))) . '\';return false;" title="' . htmlentities ( $title ) . '" href="?/' . $href . '">' . $text . '</a>' ;
2012-08-27 07:19:05 +02:00
}
function secure_link ( $href ) {
return $href . '/' . make_secure_link_token ( $href );
2012-04-11 18:49:22 +02:00
}
2013-07-20 00:36:12 +02:00
function embed_html ( $link ) {
global $config ;
foreach ( $config [ 'embedding' ] as $embed ) {
if ( $html = preg_replace ( $embed [ 0 ], $embed [ 1 ], $link )) {
if ( $html == $link )
continue ; // Nope
$html = str_replace ( '%%tb_width%%' , $config [ 'embed_width' ], $html );
$html = str_replace ( '%%tb_height%%' , $config [ 'embed_height' ], $html );
return $html ;
}
}
if ( $link [ 0 ] == '<' ) {
// Prior to v0.9.6-dev-8, HTML code for embedding was stored in the database instead of the link.
return $link ;
}
return 'Embedding error.' ;
}
2012-04-11 18:49:22 +02:00
class Post {
2013-08-16 13:08:01 +02:00
public function __construct ( $post , $root = null , $mod = false ) {
2011-04-17 07:28:15 +02:00
global $config ;
2012-04-12 16:18:19 +02:00
if ( ! isset ( $root ))
2012-04-11 18:49:22 +02:00
$root = & $config [ 'root' ];
2012-02-11 08:53:27 +01:00
2013-08-16 13:08:01 +02:00
foreach ( $post as $key => $value ) {
$this -> { $key } = $value ;
}
$this -> subject = utf8tohtml ( $this -> subject );
$this -> name = utf8tohtml ( $this -> name );
2012-04-11 18:49:22 +02:00
$this -> mod = $mod ;
2013-08-16 13:08:01 +02:00
$this -> root = $root ;
2011-04-17 07:28:15 +02:00
2013-07-20 00:36:12 +02:00
if ( $this -> embed )
$this -> embed = embed_html ( $this -> embed );
2013-08-16 13:08:01 +02:00
$this -> modifiers = extract_modifiers ( $this -> body_nomarkup );
2013-08-29 07:29:04 +02:00
if ( $config [ 'always_regenerate_markup' ]) {
$this -> body = $this -> body_nomarkup ;
markup ( $this -> body );
}
2012-04-12 16:18:19 +02:00
if ( $this -> mod )
2012-04-11 18:49:22 +02:00
// Fix internal links
// Very complicated regex
$this -> body = preg_replace (
2013-07-31 08:08:55 +02:00
'/<a((([a-zA-Z]+="[^"]+")|[a-zA-Z]+=[a-zA-Z]+|\s)*)href="' . preg_quote ( $config [ 'root' ], '/' ) . '(' . sprintf ( preg_quote ( $config [ 'board_path' ], '/' ), $config [ 'board_regex' ]) . ')/u' ,
2012-04-11 18:49:22 +02:00
'<a $1href="?/$4' ,
$this -> body
);
}
public function link ( $pre = '' ) {
global $config , $board ;
2011-04-17 07:28:15 +02:00
2012-04-11 18:49:22 +02:00
return $this -> root . $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] . sprintf ( $config [ 'file_page' ], $this -> thread ) . '#' . $pre . $this -> id ;
}
public function postControls () {
global $board , $config ;
2011-04-17 07:28:15 +02:00
2012-04-11 18:49:22 +02:00
$built = '' ;
2012-04-12 16:18:19 +02:00
if ( $this -> mod ) {
2012-04-11 18:49:22 +02:00
// Mod controls (on posts)
2011-04-17 07:28:15 +02:00
2012-04-11 18:49:22 +02:00
// Delete
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'delete' ], $board [ 'uri' ], $this -> mod ))
2013-08-03 02:52:58 +02:00
$built .= ' ' . secure_link_confirm ( $config [ 'mod' ][ 'link_delete' ], 'Delete' , 'Are you sure you want to delete this?' , $board [ 'dir' ] . 'delete/' . $this -> id );
2012-04-11 18:49:22 +02:00
// Delete all posts by IP
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'deletebyip' ], $board [ 'uri' ], $this -> mod ))
2013-08-03 02:52:58 +02:00
$built .= ' ' . secure_link_confirm ( $config [ 'mod' ][ 'link_deletebyip' ], 'Delete all posts by IP' , 'Are you sure you want to delete all posts by this IP address?' , $board [ 'dir' ] . 'deletebyip/' . $this -> id );
2012-04-11 18:49:22 +02:00
// Delete all posts by IP (global)
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'deletebyip_global' ], $board [ 'uri' ], $this -> mod ))
2013-08-03 02:52:58 +02:00
$built .= ' ' . secure_link_confirm ( $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 [ 'dir' ] . 'deletebyip/' . $this -> id . '/global' );
2012-04-11 18:49:22 +02:00
// Ban
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'ban' ], $board [ 'uri' ], $this -> mod ))
2013-08-03 02:52:58 +02:00
$built .= ' <a title="' . _ ( 'Ban' ) . '" href="?/' . $board [ 'dir' ] . 'ban/' . $this -> id . '">' . $config [ 'mod' ][ 'link_ban' ] . '</a>' ;
2012-04-11 18:49:22 +02:00
// Ban & Delete
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'bandelete' ], $board [ 'uri' ], $this -> mod ))
2013-08-03 02:52:58 +02:00
$built .= ' <a title="' . _ ( 'Ban & Delete' ) . '" href="?/' . $board [ 'dir' ] . 'ban&delete/' . $this -> id . '">' . $config [ 'mod' ][ 'link_bandelete' ] . '</a>' ;
2012-02-11 08:53:27 +01:00
2012-04-11 18:49:22 +02:00
// Delete file (keep post)
2012-04-12 16:18:19 +02:00
if ( ! empty ( $this -> file ) && hasPermission ( $config [ 'mod' ][ 'deletefile' ], $board [ 'uri' ], $this -> mod ))
2013-08-03 02:52:58 +02:00
$built .= ' ' . secure_link_confirm ( $config [ 'mod' ][ 'link_deletefile' ], _ ( 'Delete file' ), _ ( 'Are you sure you want to delete this file?' ), $board [ 'dir' ] . 'deletefile/' . $this -> id );
2012-04-11 18:49:22 +02:00
2013-08-08 21:41:21 +02:00
// Spoiler file (keep post)
2013-08-08 21:43:40 +02:00
if ( ! empty ( $this -> file ) && $this -> file != " deleted " && $this -> file != null && $this -> thumb != 'spoiler' && hasPermission ( $config [ 'mod' ][ 'spoilerimage' ], $board [ 'uri' ], $this -> mod ) && $config [ 'spoiler_images' ])
2013-08-09 23:21:40 +02:00
$built .= ' ' . secure_link_confirm ( $config [ 'mod' ][ 'link_spoilerimage' ], _ ( 'Spoiler File' ), _ ( 'Are you sure you want to spoiler this file?' ), $board [ 'uri' ] . '/spoiler/' . $this -> id );
2013-08-08 21:41:21 +02:00
2013-08-08 23:08:01 +02:00
// Move post
if ( hasPermission ( $config [ 'mod' ][ 'move' ], $board [ 'uri' ], $this -> mod ) && $config [ 'move_replies' ])
2013-08-09 23:21:40 +02:00
$built .= ' <a title="' . _ ( 'Move reply to another board' ) . '" href="?/' . $board [ 'uri' ] . '/move_reply/' . $this -> id . '">' . $config [ 'mod' ][ 'link_move' ] . '</a>' ;
2013-08-08 23:08:01 +02:00
2012-04-11 18:49:22 +02:00
// Edit post
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'editpost' ], $board [ 'uri' ], $this -> mod ))
2013-08-03 02:52:58 +02:00
$built .= ' <a title="' . _ ( 'Edit post' ) . '" href="?/' . $board [ 'dir' ] . 'edit' . ( $config [ 'mod' ][ 'raw_html_default' ] ? '_raw' : '' ) . '/' . $this -> id . '">' . $config [ 'mod' ][ 'link_editpost' ] . '</a>' ;
2013-08-08 23:08:01 +02:00
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( ! empty ( $built ))
2012-04-11 18:49:22 +02:00
$built = '<span class="controls">' . $built . '</span>' ;
2011-04-17 07:28:15 +02:00
}
2012-04-11 18:49:22 +02:00
return $built ;
2011-04-17 07:28:15 +02:00
}
2013-08-16 20:11:24 +02:00
public function ratio () {
return fraction ( $this -> filewidth , $this -> fileheight , ':' );
}
2012-04-11 18:49:22 +02:00
public function build ( $index = false ) {
global $board , $config ;
2012-08-27 13:50:15 +02:00
return Element ( 'post_reply.html' , array ( 'config' => $config , 'board' => $board , 'post' => & $this , 'index' => $index ));
2011-04-06 10:31:26 +02:00
}
2012-04-11 18:49:22 +02:00
};
class Thread {
2013-08-16 13:08:01 +02:00
public function __construct ( $post , $root = null , $mod = false , $hr = true ) {
2012-04-11 18:49:22 +02:00
global $config ;
2012-04-12 16:18:19 +02:00
if ( ! isset ( $root ))
2012-04-11 18:49:22 +02:00
$root = & $config [ 'root' ];
2013-08-16 13:08:01 +02:00
foreach ( $post as $key => $value ) {
$this -> { $key } = $value ;
}
$this -> subject = utf8tohtml ( $this -> subject );
$this -> name = utf8tohtml ( $this -> name );
2012-04-11 18:49:22 +02:00
$this -> mod = $mod ;
2013-08-16 13:08:01 +02:00
$this -> root = $root ;
2012-04-11 18:49:22 +02:00
$this -> hr = $hr ;
2013-08-16 13:08:01 +02:00
$this -> posts = array ();
2012-04-11 18:49:22 +02:00
$this -> omitted = 0 ;
$this -> omitted_images = 0 ;
2013-07-20 00:36:12 +02:00
if ( $this -> embed )
$this -> embed = embed_html ( $this -> embed );
2013-08-16 13:08:01 +02:00
$this -> modifiers = extract_modifiers ( $this -> body_nomarkup );
2013-08-29 07:29:04 +02:00
if ( $config [ 'always_regenerate_markup' ]) {
$this -> body = $this -> body_nomarkup ;
markup ( $this -> body );
}
2012-04-12 16:18:19 +02:00
if ( $this -> mod )
2012-04-11 18:49:22 +02:00
// Fix internal links
// Very complicated regex
$this -> body = preg_replace (
2013-07-31 08:08:55 +02:00
'/<a((([a-zA-Z]+="[^"]+")|[a-zA-Z]+=[a-zA-Z]+|\s)*)href="' . preg_quote ( $config [ 'root' ], '/' ) . '(' . sprintf ( preg_quote ( $config [ 'board_path' ], '/' ), $config [ 'board_regex' ]) . ')/u' ,
2012-11-03 05:29:11 +01:00
'<a $1href="?/$4' ,
2012-04-11 18:49:22 +02:00
$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 ;
}
2013-08-10 23:16:30 +02:00
public function postCount () {
return count ( $this -> posts ) + $this -> omitted ;
}
2012-04-11 18:49:22 +02:00
public function postControls () {
global $board , $config ;
$built = '' ;
2012-04-12 16:18:19 +02:00
if ( $this -> mod ) {
2012-04-11 18:49:22 +02:00
// Mod controls (on posts)
// Delete
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'delete' ], $board [ 'uri' ], $this -> mod ))
2013-08-03 02:52:58 +02:00
$built .= ' ' . secure_link_confirm ( $config [ 'mod' ][ 'link_delete' ], _ ( 'Delete' ), _ ( 'Are you sure you want to delete this?' ), $board [ 'dir' ] . 'delete/' . $this -> id );
2011-02-12 07:25:15 +01:00
2012-04-11 18:49:22 +02:00
// Delete all posts by IP
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'deletebyip' ], $board [ 'uri' ], $this -> mod ))
2013-08-03 02:52:58 +02:00
$built .= ' ' . secure_link_confirm ( $config [ 'mod' ][ 'link_deletebyip' ], _ ( 'Delete all posts by IP' ), _ ( 'Are you sure you want to delete all posts by this IP address?' ), $board [ 'dir' ] . 'deletebyip/' . $this -> id );
2011-02-06 14:37:26 +01:00
2012-04-11 18:49:22 +02:00
// Delete all posts by IP (global)
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'deletebyip_global' ], $board [ 'uri' ], $this -> mod ))
2013-08-03 02:52:58 +02:00
$built .= ' ' . secure_link_confirm ( $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 [ 'dir' ] . 'deletebyip/' . $this -> id . '/global' );
2011-04-17 07:28:15 +02:00
2012-04-11 18:49:22 +02:00
// Ban
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'ban' ], $board [ 'uri' ], $this -> mod ))
2013-08-03 02:52:58 +02:00
$built .= ' <a title="' . _ ( 'Ban' ) . '" href="?/' . $board [ 'dir' ] . 'ban/' . $this -> id . '">' . $config [ 'mod' ][ 'link_ban' ] . '</a>' ;
2011-01-18 06:48:39 +01:00
2012-04-11 18:49:22 +02:00
// Ban & Delete
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'bandelete' ], $board [ 'uri' ], $this -> mod ))
2013-08-03 02:52:58 +02:00
$built .= ' <a title="' . _ ( 'Ban & Delete' ) . '" href="?/' . $board [ 'dir' ] . 'ban&delete/' . $this -> id . '">' . $config [ 'mod' ][ 'link_bandelete' ] . '</a>' ;
2011-05-19 13:50:19 +02:00
2012-04-11 18:49:22 +02:00
// Delete file (keep post)
2012-04-12 16:18:19 +02:00
if ( ! empty ( $this -> file ) && $this -> file != 'deleted' && hasPermission ( $config [ 'mod' ][ 'deletefile' ], $board [ 'uri' ], $this -> mod ))
2013-08-03 02:52:58 +02:00
$built .= ' ' . secure_link_confirm ( $config [ 'mod' ][ 'link_deletefile' ], _ ( 'Delete file' ), _ ( 'Are you sure you want to delete this file?' ), $board [ 'dir' ] . 'deletefile/' . $this -> id );
2013-08-08 21:41:21 +02:00
// Spoiler file (keep post)
2013-08-08 21:43:40 +02:00
if ( ! empty ( $this -> file ) && $this -> file != " deleted " && $this -> file != null && $this -> thumb != 'spoiler' && hasPermission ( $config [ 'mod' ][ 'spoilerimage' ], $board [ 'uri' ], $this -> mod ) && $config [ 'spoiler_images' ])
2013-08-09 23:21:40 +02:00
$built .= ' ' . secure_link_confirm ( $config [ 'mod' ][ 'link_spoilerimage' ], _ ( 'Spoiler File' ), _ ( 'Are you sure you want to spoiler this file?' ), $board [ 'uri' ] . '/spoiler/' . $this -> id );
2011-02-12 07:25:15 +01:00
2012-04-11 18:49:22 +02:00
// Sticky
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'sticky' ], $board [ 'uri' ], $this -> mod ))
if ( $this -> sticky )
2013-08-03 02:52:58 +02:00
$built .= ' <a title="' . _ ( 'Make thread not sticky' ) . '" href="?/' . secure_link ( $board [ 'dir' ] . 'unsticky/' . $this -> id ) . '">' . $config [ 'mod' ][ 'link_desticky' ] . '</a>' ;
2012-04-11 18:49:22 +02:00
else
2013-08-03 02:52:58 +02:00
$built .= ' <a title="' . _ ( 'Make thread sticky' ) . '" href="?/' . secure_link ( $board [ 'dir' ] . 'sticky/' . $this -> id ) . '">' . $config [ 'mod' ][ 'link_sticky' ] . '</a>' ;
2011-02-06 14:37:26 +01:00
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'bumplock' ], $board [ 'uri' ], $this -> mod ))
2013-08-16 13:08:01 +02:00
if ( $this -> sage )
2013-08-03 02:52:58 +02:00
$built .= ' <a title="' . _ ( 'Allow thread to be bumped' ) . '" href="?/' . secure_link ( $board [ 'dir' ] . 'bumpunlock/' . $this -> id ) . '">' . $config [ 'mod' ][ 'link_bumpunlock' ] . '</a>' ;
2012-04-11 18:49:22 +02:00
else
2013-08-03 02:52:58 +02:00
$built .= ' <a title="' . _ ( 'Prevent thread from being bumped' ) . '" href="?/' . secure_link ( $board [ 'dir' ] . 'bumplock/' . $this -> id ) . '">' . $config [ 'mod' ][ 'link_bumplock' ] . '</a>' ;
2011-04-17 07:28:15 +02:00
2012-04-11 18:49:22 +02:00
// Lock
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'lock' ], $board [ 'uri' ], $this -> mod ))
if ( $this -> locked )
2013-08-03 02:52:58 +02:00
$built .= ' <a title="' . _ ( 'Unlock thread' ) . '" href="?/' . secure_link ( $board [ 'dir' ] . 'unlock/' . $this -> id ) . '">' . $config [ 'mod' ][ 'link_unlock' ] . '</a>' ;
2012-04-11 18:49:22 +02:00
else
2013-08-03 02:52:58 +02:00
$built .= ' <a title="' . _ ( 'Lock thread' ) . '" href="?/' . secure_link ( $board [ 'dir' ] . 'lock/' . $this -> id ) . '">' . $config [ 'mod' ][ 'link_lock' ] . '</a>' ;
2011-01-18 06:48:39 +01:00
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'move' ], $board [ 'uri' ], $this -> mod ))
2013-08-03 02:52:58 +02:00
$built .= ' <a title="' . _ ( 'Move thread to another board' ) . '" href="?/' . $board [ 'dir' ] . 'move/' . $this -> id . '">' . $config [ 'mod' ][ 'link_move' ] . '</a>' ;
2010-12-10 11:14:45 +01:00
2012-04-11 18:49:22 +02:00
// Edit post
2012-04-12 16:18:19 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'editpost' ], $board [ 'uri' ], $this -> mod ))
2013-08-03 02:52:58 +02:00
$built .= ' <a title="' . _ ( 'Edit post' ) . '" href="?/' . $board [ 'dir' ] . 'edit' . ( $config [ 'mod' ][ 'raw_html_default' ] ? '_raw' : '' ) . '/' . $this -> id . '">' . $config [ 'mod' ][ 'link_editpost' ] . '</a>' ;
2010-11-04 07:16:47 +01:00
2012-04-12 16:18:19 +02:00
if ( ! empty ( $built ))
2012-04-11 18:49:22 +02:00
$built = '<span class="controls op">' . $built . '</span>' ;
2010-11-02 11:57:33 +01:00
}
2012-04-11 18:49:22 +02:00
return $built ;
}
2013-08-16 20:11:24 +02:00
public function ratio () {
return fraction ( $this -> filewidth , $this -> fileheight , ':' );
}
2013-08-10 23:16:30 +02:00
public function build ( $index = false , $isnoko50 = false ) {
2012-04-11 18:49:22 +02:00
global $board , $config , $debug ;
2013-08-10 23:16:30 +02:00
$hasnoko50 = $this -> postCount () >= $config [ 'noko50_min' ];
2013-09-17 16:43:44 +02:00
event ( 'show-thread' , $this );
2013-08-10 23:16:30 +02:00
$built = Element ( 'post_thread.html' , array ( 'config' => $config , 'board' => $board , 'post' => & $this , 'index' => $index , 'hasnoko50' => $hasnoko50 , 'isnoko50' => $isnoko50 ));
2012-04-11 18:49:22 +02:00
return $built ;
}
};