2012-04-12 18:11:41 +02:00
< ? php
/*
2013-01-20 11:23:46 +01:00
* Copyright ( c ) 2010 - 2013 Tinyboard Development Group
2012-04-12 18:11:41 +02:00
*/
2024-08-15 17:05:43 +02:00
use Vichan\Context ;
2024-04-30 12:32:40 +02:00
use Vichan\Functions\Format ;
2012-04-12 18:11:41 +02:00
2024-04-30 11:31:06 +02:00
use Vichan\Functions\Net ;
2012-04-12 18:11:41 +02:00
2013-09-06 12:12:04 +02:00
defined ( 'TINYBOARD' ) or exit ;
2012-04-12 18:11:41 +02:00
2024-04-30 11:31:06 +02:00
2024-08-18 01:06:45 +02:00
function _link_or_copy ( string $target , string $link ) : bool {
if ( ! link ( $target , $link )) {
error_log ( " Failed to link() $target to $link . Falling back to copy() " );
return copy ( $target , $link );
}
return true ;
}
2012-05-05 17:33:10 +02:00
function mod_page ( $title , $template , $args , $subtitle = false ) {
2012-04-12 18:11:41 +02:00
global $config , $mod ;
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
echo Element ( $config [ 'file_page_template' ], array (
2012-04-12 18:11:41 +02:00
'config' => $config ,
'mod' => $mod ,
2022-08-29 16:50:45 +02:00
'hide_dashboard_link' => $template == $config [ 'file_mod_dashboard' ],
2012-04-12 18:11:41 +02:00
'title' => $title ,
2012-05-05 17:33:10 +02:00
'subtitle' => $subtitle ,
2016-05-05 09:56:54 +02:00
'boardlist' => createBoardlist ( $mod ),
2012-04-12 18:11:41 +02:00
'body' => Element ( $template ,
array_merge (
2024-02-23 22:49:23 +01:00
array ( 'config' => $config , 'mod' => $mod ),
2012-04-12 18:11:41 +02:00
$args
)
)
)
);
}
2024-08-15 17:05:43 +02:00
function mod_login ( Context $ctx , $redirect = false ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2024-04-30 11:31:06 +02:00
$args = [];
2024-02-23 22:49:23 +01:00
2024-05-11 16:02:15 +02:00
$secure_login_mode = $config [ 'cookies' ][ 'secure_login_only' ];
if ( $secure_login_mode !== 0 && ! Net\is_connection_secure ( $secure_login_mode === 1 )) {
2024-04-30 11:31:06 +02:00
$args [ 'error' ] = $config [ 'error' ][ 'insecure' ];
} elseif ( isset ( $_POST [ 'login' ])) {
2012-04-12 18:11:41 +02:00
// Check if inputs are set and not empty
if ( ! isset ( $_POST [ 'username' ], $_POST [ 'password' ]) || $_POST [ 'username' ] == '' || $_POST [ 'password' ] == '' ) {
$args [ 'error' ] = $config [ 'error' ][ 'invalid' ];
} elseif ( ! login ( $_POST [ 'username' ], $_POST [ 'password' ])) {
if ( $config [ 'syslog' ])
_syslog ( LOG_WARNING , 'Unauthorized login attempt!' );
2024-02-23 22:49:23 +01:00
2012-04-12 18:11:41 +02:00
$args [ 'error' ] = $config [ 'error' ][ 'invalid' ];
} else {
2012-04-16 08:40:24 +02:00
modLog ( 'Logged in' );
2024-02-23 22:49:23 +01:00
2012-04-12 18:11:41 +02:00
// Login successful
// Set cookies
setCookies ();
2024-02-23 22:49:23 +01:00
2013-01-29 12:11:33 +01:00
if ( $redirect )
header ( 'Location: ?' . $redirect , true , $config [ 'redirect_http' ]);
else
header ( 'Location: ?/' , true , $config [ 'redirect_http' ]);
2012-04-12 18:11:41 +02:00
}
}
2024-02-23 22:49:23 +01:00
2012-04-12 18:11:41 +02:00
if ( isset ( $_POST [ 'username' ]))
$args [ 'username' ] = $_POST [ 'username' ];
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Login' ), $config [ 'file_mod_login' ], $args );
2012-04-13 02:41:30 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_confirm ( Context $ctx , $request ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Confirm action' ), $config [ 'file_mod_confim' ], array ( 'request' => $request , 'token' => make_secure_link_token ( $request )));
2012-04-12 18:11:41 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_logout ( Context $ctx ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2012-05-05 17:33:10 +02:00
destroyCookies ();
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
header ( 'Location: ?/' , true , $config [ 'redirect_http' ]);
}
2024-08-15 17:05:43 +02:00
function mod_dashboard ( Context $ctx ) {
2024-08-15 17:12:14 +02:00
global $mod ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2024-08-15 17:21:41 +02:00
$args = [];
2024-02-23 22:49:23 +01:00
2012-04-12 18:11:41 +02:00
$args [ 'boards' ] = listBoards ();
2024-02-23 22:49:23 +01:00
2012-04-21 07:15:32 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'noticeboard' ])) {
if ( ! $config [ 'cache' ][ 'enabled' ] || ! $args [ 'noticeboard' ] = cache :: get ( 'noticeboard_preview' )) {
2013-08-01 04:14:26 +02:00
$query = prepare ( " SELECT ``noticeboard``.*, `username` FROM ``noticeboard`` LEFT JOIN ``mods`` ON ``mods``.`id` = `mod` ORDER BY `id` DESC LIMIT :limit " );
2012-04-20 13:54:30 +02:00
$query -> bindValue ( ':limit' , $config [ 'mod' ][ 'noticeboard_dashboard' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
$args [ 'noticeboard' ] = $query -> fetchAll ( PDO :: FETCH_ASSOC );
2024-02-23 22:49:23 +01:00
2012-04-21 07:15:32 +02:00
if ( $config [ 'cache' ][ 'enabled' ])
2012-04-20 13:54:30 +02:00
cache :: set ( 'noticeboard_preview' , $args [ 'noticeboard' ]);
}
}
2024-02-23 22:49:23 +01:00
2013-08-30 00:38:14 +02:00
if ( ! $config [ 'cache' ][ 'enabled' ] || ( $args [ 'unread_pms' ] = cache :: get ( 'pm_unreadcount_' . $mod [ 'id' ])) === false ) {
2013-08-01 04:14:26 +02:00
$query = prepare ( 'SELECT COUNT(*) FROM ``pms`` WHERE `to` = :id AND `unread` = 1' );
2012-05-20 11:06:27 +02:00
$query -> bindValue ( ':id' , $mod [ 'id' ]);
$query -> execute () or error ( db_error ( $query ));
2013-08-01 02:51:43 +02:00
$args [ 'unread_pms' ] = $query -> fetchColumn ();
2024-02-23 22:49:23 +01:00
2012-05-20 11:06:27 +02:00
if ( $config [ 'cache' ][ 'enabled' ])
cache :: set ( 'pm_unreadcount_' . $mod [ 'id' ], $args [ 'unread_pms' ]);
}
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = query ( 'SELECT COUNT(*) FROM ``reports``' ) or error ( db_error ( $query ));
2013-08-01 02:51:43 +02:00
$args [ 'reports' ] = $query -> fetchColumn ();
2024-02-23 22:49:23 +01:00
2021-07-24 08:32:45 +02:00
$query = query ( 'SELECT COUNT(*) FROM ``ban_appeals``' ) or error ( db_error ( $query ));
$args [ 'appeals' ] = $query -> fetchColumn ();
2012-05-05 17:33:10 +02:00
if ( $mod [ 'type' ] >= ADMIN && $config [ 'check_updates' ]) {
if ( ! $config [ 'version' ])
error ( _ ( 'Could not find current version! (Check .installed)' ));
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( isset ( $_COOKIE [ 'update' ])) {
$latest = unserialize ( $_COOKIE [ 'update' ]);
} else {
$ctx = stream_context_create ( array ( 'http' => array ( 'timeout' => 5 )));
2024-03-12 02:54:20 +01:00
if ( $code = @ file_get_contents ( 'http://engine.vichan.info/version.txt' , 0 , $ctx )) {
2013-03-14 14:40:02 +01:00
$ver = strtok ( $code , " \n " );
2024-02-23 22:49:23 +01:00
2013-03-14 14:40:02 +01:00
if ( preg_match ( '@^// v(\d+)\.(\d+)\.(\d+)\s*?$@' , $ver , $matches )) {
$latest = array (
'massive' => $matches [ 1 ],
'major' => $matches [ 2 ],
'minor' => $matches [ 3 ]
2012-05-05 17:33:10 +02:00
);
2015-04-23 08:18:36 +02:00
if ( preg_match ( '/(\d+)\.(\d)\.(\d+)(-dev.+)?$/' , $config [ 'version' ], $matches )) {
2013-03-14 14:40:02 +01:00
$current = array (
'massive' => ( int ) $matches [ 1 ],
'major' => ( int ) $matches [ 2 ],
'minor' => ( int ) $matches [ 3 ]
);
2024-02-23 22:49:23 +01:00
if ( isset ( $m [ 4 ])) {
2013-03-14 14:40:02 +01:00
// Development versions are always ahead in the versioning numbers
$current [ 'minor' ] -- ;
}
// Check if it's newer
if ( ! ( $latest [ 'massive' ] > $current [ 'massive' ] ||
$latest [ 'major' ] > $current [ 'major' ] ||
( $latest [ 'massive' ] == $current [ 'massive' ] &&
$latest [ 'major' ] == $current [ 'major' ] &&
$latest [ 'minor' ] > $current [ 'minor' ]
)))
$latest = false ;
} else {
2012-05-05 17:33:10 +02:00
$latest = false ;
2013-03-14 14:40:02 +01:00
}
2012-05-05 17:33:10 +02:00
} else {
2013-03-14 14:40:02 +01:00
// Couldn't get latest version
2012-05-05 17:33:10 +02:00
$latest = false ;
}
} else {
// Couldn't get latest version
$latest = false ;
}
2024-02-23 22:49:23 +01:00
2014-06-11 06:07:45 +02:00
setcookie ( 'update' , serialize ( $latest ), time () + $config [ 'check_updates_time' ], $config [ 'cookies' ][ 'jail' ] ? $config [ 'cookies' ][ 'path' ] : '/' , null , ! empty ( $_SERVER [ 'HTTPS' ]) && $_SERVER [ 'HTTPS' ] != 'off' , true );
2012-05-05 17:33:10 +02:00
}
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( $latest )
$args [ 'newer_release' ] = $latest ;
}
2024-02-23 22:49:23 +01:00
2013-09-23 08:48:56 +02:00
$args [ 'logout_token' ] = make_secure_link_token ( 'logout' );
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Dashboard' ), $config [ 'file_mod_dashboard' ], $args );
2012-04-12 18:11:41 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_search_redirect ( Context $ctx ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2013-07-20 13:50:33 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'search' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-07-20 18:05:42 +02:00
if ( isset ( $_POST [ 'query' ], $_POST [ 'type' ]) && in_array ( $_POST [ 'type' ], array ( 'posts' , 'IP_notes' , 'bans' , 'log' ))) {
2013-07-20 13:50:33 +02:00
$query = $_POST [ 'query' ];
$query = urlencode ( $query );
$query = str_replace ( '_' , '%5F' , $query );
$query = str_replace ( '+' , '_' , $query );
2024-02-23 22:49:23 +01:00
2013-07-30 02:20:07 +02:00
if ( $query === '' ) {
header ( 'Location: ?/' , true , $config [ 'redirect_http' ]);
return ;
}
2024-02-23 22:49:23 +01:00
2013-07-20 13:50:33 +02:00
header ( 'Location: ?/search/' . $_POST [ 'type' ] . '/' . $query , true , $config [ 'redirect_http' ]);
} else {
header ( 'Location: ?/' , true , $config [ 'redirect_http' ]);
}
}
2024-08-15 17:05:43 +02:00
function mod_search ( Context $ctx , $type , $search_query_escaped , $page_no = 1 ) {
2013-07-20 13:50:33 +02:00
global $pdo , $config ;
2024-02-23 22:49:23 +01:00
2013-07-20 13:50:33 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'search' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-07-20 13:50:33 +02:00
// Unescape query
2013-07-20 18:05:42 +02:00
$query = str_replace ( '_' , ' ' , $search_query_escaped );
2013-07-20 13:50:33 +02:00
$query = urldecode ( $query );
$search_query = $query ;
2024-02-23 22:49:23 +01:00
2013-07-20 13:50:33 +02:00
// Form a series of LIKE clauses for the query.
// This gets a little complicated.
2024-02-23 22:49:23 +01:00
2013-07-20 13:50:33 +02:00
// Escape "escape" character
$query = str_replace ( '!' , '!!' , $query );
2024-02-23 22:49:23 +01:00
2013-07-20 13:50:33 +02:00
// Escape SQL wildcard
$query = str_replace ( '%' , '!%' , $query );
2024-02-23 22:49:23 +01:00
2013-07-20 13:50:33 +02:00
// Use asterisk as wildcard instead
$query = str_replace ( '*' , '%' , $query );
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = str_replace ( '`' , '!`' , $query );
2024-02-23 22:49:23 +01:00
2013-07-20 13:50:33 +02:00
// Array of phrases to match
2024-08-15 17:21:41 +02:00
$match = [];
2013-09-30 04:18:56 +02:00
2013-07-20 13:50:33 +02:00
// Exact phrases ("like this")
2013-07-20 18:05:42 +02:00
if ( preg_match_all ( '/"(.+?)"/' , $query , $exact_phrases )) {
$exact_phrases = $exact_phrases [ 1 ];
foreach ( $exact_phrases as $phrase ) {
2013-07-20 13:50:33 +02:00
$query = str_replace ( " \" { $phrase } \" " , '' , $query );
$match [] = $pdo -> quote ( $phrase );
}
}
2024-02-23 22:49:23 +01:00
2013-07-20 13:50:33 +02:00
// Non-exact phrases (ie. plain keywords)
$keywords = explode ( ' ' , $query );
foreach ( $keywords as $word ) {
if ( empty ( $word ))
continue ;
$match [] = $pdo -> quote ( $word );
}
2024-02-23 22:49:23 +01:00
2013-07-20 13:50:33 +02:00
// Which `field` to search?
if ( $type == 'posts' )
2014-07-08 09:43:04 +02:00
$sql_field = array ( 'body_nomarkup' , 'files' , 'subject' , 'filehash' , 'ip' , 'name' , 'trip' );
2013-07-20 13:50:33 +02:00
if ( $type == 'IP_notes' )
$sql_field = 'body' ;
if ( $type == 'bans' )
$sql_field = 'reason' ;
2013-07-20 18:05:42 +02:00
if ( $type == 'log' )
$sql_field = 'text' ;
2013-09-30 04:18:56 +02:00
2013-07-20 13:50:33 +02:00
// Build the "LIKE 'this' AND LIKE 'that'" etc. part of the SQL query
$sql_like = '' ;
foreach ( $match as $phrase ) {
if ( ! empty ( $sql_like ))
$sql_like .= ' AND ' ;
$phrase = preg_replace ( '/^\'(.+)\'$/' , '\'%$1%\'' , $phrase );
2013-07-30 02:20:07 +02:00
if ( is_array ( $sql_field )) {
foreach ( $sql_field as $field ) {
$sql_like .= '`' . $field . '` LIKE ' . $phrase . ' ESCAPE \'!\' OR' ;
}
$sql_like = preg_replace ( '/ OR$/' , '' , $sql_like );
} else {
$sql_like .= '`' . $sql_field . '` LIKE ' . $phrase . ' ESCAPE \'!\'' ;
}
2013-07-20 13:50:33 +02:00
}
2024-02-23 22:49:23 +01:00
2013-07-20 18:05:42 +02:00
// Compile SQL query
2024-02-23 22:49:23 +01:00
2013-07-20 13:50:33 +02:00
if ( $type == 'posts' ) {
2013-07-29 22:18:06 +02:00
$query = '' ;
$boards = listBoards ();
if ( empty ( $boards ))
error ( _ ( 'There are no boards to search!' ));
2024-02-23 22:49:23 +01:00
2013-07-29 22:18:06 +02:00
foreach ( $boards as $board ) {
openBoard ( $board [ 'uri' ]);
if ( ! hasPermission ( $config [ 'mod' ][ 'search_posts' ], $board [ 'uri' ]))
continue ;
2024-02-23 22:49:23 +01:00
2013-07-29 22:18:06 +02:00
if ( ! empty ( $query ))
$query .= ' UNION ALL ' ;
2013-08-01 04:14:26 +02:00
$query .= sprintf ( " SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE %s " , $board [ 'uri' ], $board [ 'uri' ], $sql_like );
2013-07-29 22:18:06 +02:00
}
2024-02-23 22:49:23 +01:00
2013-07-29 22:18:06 +02:00
// You weren't allowed to search any boards
if ( empty ( $query ))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-07-29 22:18:06 +02:00
$query .= ' ORDER BY `sticky` DESC, `id` DESC' ;
2013-07-20 13:50:33 +02:00
}
2024-02-23 22:49:23 +01:00
2013-07-20 13:50:33 +02:00
if ( $type == 'IP_notes' ) {
2013-08-01 04:14:26 +02:00
$query = 'SELECT * FROM ``ip_notes`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` WHERE ' . $sql_like . ' ORDER BY `time` DESC' ;
2013-07-20 18:05:42 +02:00
$sql_table = 'ip_notes' ;
2013-07-20 19:15:44 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'view_notes' ]) || ! hasPermission ( $config [ 'mod' ][ 'show_ip' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2013-07-20 13:50:33 +02:00
}
2024-02-23 22:49:23 +01:00
2013-07-20 13:50:33 +02:00
if ( $type == 'bans' ) {
2013-09-17 01:35:13 +02:00
$query = 'SELECT ``bans``.*, `username` FROM ``bans`` LEFT JOIN ``mods`` ON `creator` = ``mods``.`id` WHERE ' . $sql_like . ' ORDER BY (`expires` IS NOT NULL AND `expires` < UNIX_TIMESTAMP()), `created` DESC' ;
2013-07-20 18:05:42 +02:00
$sql_table = 'bans' ;
2013-07-20 19:15:44 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'view_banlist' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2013-07-20 18:05:42 +02:00
}
2024-02-23 22:49:23 +01:00
2013-07-20 18:05:42 +02:00
if ( $type == 'log' ) {
2013-08-01 04:14:26 +02:00
$query = 'SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM ``modlogs`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` WHERE ' . $sql_like . ' ORDER BY `time` DESC' ;
2013-07-20 18:05:42 +02:00
$sql_table = 'modlogs' ;
2013-07-20 19:15:44 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'modlog' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2013-07-20 18:05:42 +02:00
}
2024-02-23 22:49:23 +01:00
2013-07-20 18:05:42 +02:00
// Execute SQL query (with pages)
$q = query ( $query . ' LIMIT ' . (( $page_no - 1 ) * $config [ 'mod' ][ 'search_page' ]) . ', ' . $config [ 'mod' ][ 'search_page' ]) or error ( db_error ());
$results = $q -> fetchAll ( PDO :: FETCH_ASSOC );
2024-02-23 22:49:23 +01:00
2013-07-20 18:05:42 +02:00
// Get total result count
2013-07-29 22:18:06 +02:00
if ( $type == 'posts' ) {
$q = query ( " SELECT COUNT(*) FROM ( $query ) AS `tmp_table` " ) or error ( db_error ());
$result_count = $q -> fetchColumn ();
} else {
$q = query ( 'SELECT COUNT(*) FROM `' . $sql_table . '` WHERE ' . $sql_like ) or error ( db_error ());
$result_count = $q -> fetchColumn ();
}
2024-02-23 22:49:23 +01:00
2013-07-20 18:05:42 +02:00
if ( $type == 'bans' ) {
2013-07-20 13:50:33 +02:00
foreach ( $results as & $ban ) {
2013-09-17 01:35:13 +02:00
$ban [ 'mask' ] = Bans :: range_to_string ( array ( $ban [ 'ipstart' ], $ban [ 'ipend' ]));
if ( filter_var ( $ban [ 'mask' ], FILTER_VALIDATE_IP ) !== false )
$ban [ 'single_addr' ] = true ;
2013-07-20 13:50:33 +02:00
}
}
2024-02-23 22:49:23 +01:00
2013-07-29 22:18:06 +02:00
if ( $type == 'posts' ) {
foreach ( $results as & $post ) {
$post [ 'snippet' ] = pm_snippet ( $post [ 'body' ]);
}
}
2024-02-23 22:49:23 +01:00
2013-07-20 13:50:33 +02:00
// $results now contains the search results
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Search results' ), $config [ 'file_mod_search_results' ], array (
2013-07-20 13:50:33 +02:00
'search_type' => $type ,
'search_query' => $search_query ,
2013-07-20 18:05:42 +02:00
'search_query_escaped' => $search_query_escaped ,
'result_count' => $result_count ,
2013-07-20 13:50:33 +02:00
'results' => $results
));
}
2024-08-15 17:05:43 +02:00
function mod_edit_board ( Context $ctx , $boardName ) {
2012-05-05 17:33:10 +02:00
global $board , $config ;
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( ! openBoard ( $boardName ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'manageboards' ], $board [ 'uri' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( isset ( $_POST [ 'title' ], $_POST [ 'subtitle' ])) {
if ( isset ( $_POST [ 'delete' ])) {
if ( ! hasPermission ( $config [ 'mod' ][ 'manageboards' ], $board [ 'uri' ]))
error ( $config [ 'error' ][ 'deleteboard' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( 'DELETE FROM ``boards`` WHERE `uri` = :uri' );
2012-05-05 17:33:10 +02:00
$query -> bindValue ( ':uri' , $board [ 'uri' ]);
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2013-08-19 12:00:16 +02:00
if ( $config [ 'cache' ][ 'enabled' ]) {
cache :: delete ( 'board_' . $board [ 'uri' ]);
cache :: delete ( 'all_boards' );
}
2024-02-23 22:49:23 +01:00
2013-08-19 12:00:16 +02:00
modLog ( 'Deleted board: ' . sprintf ( $config [ 'board_abbreviation' ], $board [ 'uri' ]), false );
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
// Delete posting table
2013-08-01 04:14:26 +02:00
$query = query ( sprintf ( 'DROP TABLE IF EXISTS ``posts_%s``' , $board [ 'uri' ])) or error ( db_error ());
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
// Clear reports
2013-08-01 04:14:26 +02:00
$query = prepare ( 'DELETE FROM ``reports`` WHERE `board` = :id' );
2019-08-08 02:31:37 +02:00
$query -> bindValue ( ':id' , $board [ 'uri' ], PDO :: PARAM_STR );
2012-05-05 17:33:10 +02:00
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
// Delete from table
2013-08-01 04:14:26 +02:00
$query = prepare ( 'DELETE FROM ``boards`` WHERE `uri` = :uri' );
2019-08-08 02:31:37 +02:00
$query -> bindValue ( ':uri' , $board [ 'uri' ], PDO :: PARAM_STR );
2012-05-05 17:33:10 +02:00
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2013-08-21 13:34:18 +02:00
$query = prepare ( " SELECT `board`, `post` FROM ``cites`` WHERE `target_board` = :board ORDER BY `board` " );
2012-05-05 17:33:10 +02:00
$query -> bindValue ( ':board' , $board [ 'uri' ]);
$query -> execute () or error ( db_error ( $query ));
while ( $cite = $query -> fetch ( PDO :: FETCH_ASSOC )) {
if ( $board [ 'uri' ] != $cite [ 'board' ]) {
if ( ! isset ( $tmp_board ))
$tmp_board = $board ;
openBoard ( $cite [ 'board' ]);
rebuildPost ( $cite [ 'post' ]);
}
}
2024-02-23 22:49:23 +01:00
2013-08-21 13:34:18 +02:00
if ( isset ( $tmp_board ))
$board = $tmp_board ;
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( 'DELETE FROM ``cites`` WHERE `board` = :board OR `target_board` = :board' );
2012-05-05 17:33:10 +02:00
$query -> bindValue ( ':board' , $board [ 'uri' ]);
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( 'DELETE FROM ``antispam`` WHERE `board` = :board' );
2012-05-05 17:33:10 +02:00
$query -> bindValue ( ':board' , $board [ 'uri' ]);
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2013-07-16 08:27:20 +02:00
// Remove board from users/permissions table
2013-08-01 04:14:26 +02:00
$query = query ( 'SELECT `id`,`boards` FROM ``mods``' ) or error ( db_error ());
2013-07-16 08:27:20 +02:00
while ( $user = $query -> fetch ( PDO :: FETCH_ASSOC )) {
$user_boards = explode ( ',' , $user [ 'boards' ]);
if ( in_array ( $board [ 'uri' ], $user_boards )) {
unset ( $user_boards [ array_search ( $board [ 'uri' ], $user_boards )]);
2013-08-01 04:14:26 +02:00
$_query = prepare ( 'UPDATE ``mods`` SET `boards` = :boards WHERE `id` = :id' );
2013-07-16 08:27:20 +02:00
$_query -> bindValue ( ':boards' , implode ( ',' , $user_boards ));
$_query -> bindValue ( ':id' , $user [ 'id' ]);
$_query -> execute () or error ( db_error ( $_query ));
}
}
2024-02-23 22:49:23 +01:00
2013-08-19 12:00:16 +02:00
// Delete entire board directory
rrmdir ( $board [ 'uri' ] . '/' );
2012-05-05 17:33:10 +02:00
} else {
2013-08-01 04:14:26 +02:00
$query = prepare ( 'UPDATE ``boards`` SET `title` = :title, `subtitle` = :subtitle WHERE `uri` = :uri' );
2012-05-05 17:33:10 +02:00
$query -> bindValue ( ':uri' , $board [ 'uri' ]);
$query -> bindValue ( ':title' , $_POST [ 'title' ]);
$query -> bindValue ( ':subtitle' , $_POST [ 'subtitle' ]);
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2013-01-27 09:02:47 +01:00
modLog ( 'Edited board information for ' . sprintf ( $config [ 'board_abbreviation' ], $board [ 'uri' ]), false );
2012-05-05 17:33:10 +02:00
}
2024-02-23 22:49:23 +01:00
2012-05-19 12:52:45 +02:00
if ( $config [ 'cache' ][ 'enabled' ]) {
cache :: delete ( 'board_' . $board [ 'uri' ]);
cache :: delete ( 'all_boards' );
}
2024-02-23 22:49:23 +01:00
2024-08-16 18:32:32 +02:00
Vichan\Functions\Theme\rebuild_themes ( 'boards' );
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
header ( 'Location: ?/' , true , $config [ 'redirect_http' ]);
} else {
2022-08-29 16:50:45 +02:00
mod_page ( sprintf ( '%s: ' . $config [ 'board_abbreviation' ], _ ( 'Edit board' ), $board [ 'uri' ]), $config [ 'file_mod_board' ], array (
2013-09-23 08:48:56 +02:00
'board' => $board ,
'token' => make_secure_link_token ( 'edit/' . $board [ 'uri' ])
));
2012-05-05 17:33:10 +02:00
}
}
2024-08-15 17:05:43 +02:00
function mod_new_board ( Context $ctx ) {
2024-08-15 17:12:14 +02:00
global $board ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'newboard' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( isset ( $_POST [ 'uri' ], $_POST [ 'title' ], $_POST [ 'subtitle' ])) {
if ( $_POST [ 'uri' ] == '' )
error ( sprintf ( $config [ 'error' ][ 'required' ], 'URI' ));
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( $_POST [ 'title' ] == '' )
error ( sprintf ( $config [ 'error' ][ 'required' ], 'title' ));
2024-02-23 22:49:23 +01:00
2013-07-31 08:08:55 +02:00
if ( ! preg_match ( '/^' . $config [ 'board_regex' ] . '$/u' , $_POST [ 'uri' ]))
2012-05-05 17:33:10 +02:00
error ( sprintf ( $config [ 'error' ][ 'invalidfield' ], 'URI' ));
2024-02-23 22:49:23 +01:00
2013-07-31 12:40:57 +02:00
$bytes = 0 ;
$chars = preg_split ( '//u' , $_POST [ 'uri' ], - 1 , PREG_SPLIT_NO_EMPTY );
foreach ( $chars as $char ) {
$o = 0 ;
$ord = ordutf8 ( $char , $o );
if ( $ord > 0x0080 )
$bytes += 5 ; // @01ff
else
$bytes ++ ;
}
$bytes + strlen ( 'posts_.frm' );
2024-02-23 22:49:23 +01:00
2013-07-31 12:40:57 +02:00
if ( $bytes > 255 ) {
error ( 'Your filesystem cannot handle a board URI of that length (' . $bytes . '/255 bytes)' );
exit ;
}
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( openBoard ( $_POST [ 'uri' ])) {
error ( sprintf ( $config [ 'error' ][ 'boardexists' ], $board [ 'url' ]));
}
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( 'INSERT INTO ``boards`` VALUES (:uri, :title, :subtitle)' );
2012-05-05 17:33:10 +02:00
$query -> bindValue ( ':uri' , $_POST [ 'uri' ]);
$query -> bindValue ( ':title' , $_POST [ 'title' ]);
$query -> bindValue ( ':subtitle' , $_POST [ 'subtitle' ]);
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
modLog ( 'Created a new board: ' . sprintf ( $config [ 'board_abbreviation' ], $_POST [ 'uri' ]));
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( ! openBoard ( $_POST [ 'uri' ]))
error ( _ ( " Couldn't open board after creation. " ));
2024-02-23 22:49:23 +01:00
2013-08-04 21:23:26 +02:00
$query = Element ( 'posts.sql' , array ( 'board' => $board [ 'uri' ]));
2024-02-23 22:49:23 +01:00
2013-08-04 21:23:26 +02:00
if ( mysql_version () < 50503 )
$query = preg_replace ( '/(CHARSET=|CHARACTER SET )utf8mb4/' , '$1utf8' , $query );
2024-02-23 22:49:23 +01:00
2013-08-04 21:23:26 +02:00
query ( $query ) or error ( db_error ());
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( $config [ 'cache' ][ 'enabled' ])
2012-05-19 12:52:45 +02:00
cache :: delete ( 'all_boards' );
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
// Build the board
buildIndex ();
2024-02-23 22:49:23 +01:00
2024-08-16 18:32:32 +02:00
Vichan\Functions\Theme\rebuild_themes ( 'boards' );
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
header ( 'Location: ?/' . $board [ 'uri' ] . '/' . $config [ 'file_index' ], true , $config [ 'redirect_http' ]);
}
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'New board' ), $config [ 'file_mod_board' ], array ( 'new' => true , 'token' => make_secure_link_token ( 'new-board' )));
2012-05-05 17:33:10 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_noticeboard ( Context $ctx , $page_no = 1 ) {
2024-08-15 17:12:14 +02:00
global $pdo , $mod ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-21 07:29:57 +02:00
if ( $page_no < 1 )
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2012-04-21 07:15:32 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'noticeboard' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2012-04-21 07:15:32 +02:00
if ( isset ( $_POST [ 'subject' ], $_POST [ 'body' ])) {
if ( ! hasPermission ( $config [ 'mod' ][ 'noticeboard_post' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 00:59:54 +02:00
$_POST [ 'body' ] = escape_markup_modifiers ( $_POST [ 'body' ]);
2012-04-21 07:15:32 +02:00
markup ( $_POST [ 'body' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( 'INSERT INTO ``noticeboard`` VALUES (NULL, :mod, :time, :subject, :body)' );
2012-04-21 07:15:32 +02:00
$query -> bindValue ( ':mod' , $mod [ 'id' ]);
$query -> bindvalue ( ':time' , time ());
$query -> bindValue ( ':subject' , $_POST [ 'subject' ]);
$query -> bindValue ( ':body' , $_POST [ 'body' ]);
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( $config [ 'cache' ][ 'enabled' ])
2012-04-21 07:15:32 +02:00
cache :: delete ( 'noticeboard_preview' );
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
modLog ( 'Posted a noticeboard entry' );
2024-02-23 22:49:23 +01:00
2012-04-21 07:15:32 +02:00
header ( 'Location: ?/noticeboard#' . $pdo -> lastInsertId (), true , $config [ 'redirect_http' ]);
}
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( " SELECT ``noticeboard``.*, `username` FROM ``noticeboard`` LEFT JOIN ``mods`` ON ``mods``.`id` = `mod` ORDER BY `id` DESC LIMIT :offset, :limit " );
2012-04-21 07:15:32 +02:00
$query -> bindValue ( ':limit' , $config [ 'mod' ][ 'noticeboard_page' ], PDO :: PARAM_INT );
$query -> bindValue ( ':offset' , ( $page_no - 1 ) * $config [ 'mod' ][ 'noticeboard_page' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
$noticeboard = $query -> fetchAll ( PDO :: FETCH_ASSOC );
2024-02-23 22:49:23 +01:00
2012-04-21 07:29:57 +02:00
if ( empty ( $noticeboard ) && $page_no > 1 )
2012-04-21 07:15:32 +02:00
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2013-09-23 08:48:56 +02:00
foreach ( $noticeboard as & $entry ) {
$entry [ 'delete_token' ] = make_secure_link_token ( 'noticeboard/delete/' . $entry [ 'id' ]);
}
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( " SELECT COUNT(*) FROM ``noticeboard`` " );
2012-04-21 07:15:32 +02:00
$query -> execute () or error ( db_error ( $query ));
2013-08-01 02:51:43 +02:00
$count = $query -> fetchColumn ();
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Noticeboard' ), $config [ 'file_mod_noticeboard' ], array (
2013-09-23 08:48:56 +02:00
'noticeboard' => $noticeboard ,
'count' => $count ,
'token' => make_secure_link_token ( 'noticeboard' )
));
2012-04-21 07:15:32 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_noticeboard_delete ( Context $ctx , $id ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'noticeboard_delete' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( 'DELETE FROM ``noticeboard`` WHERE `id` = :id' );
2012-05-05 17:33:10 +02:00
$query -> bindValue ( ':id' , $id );
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
modLog ( 'Deleted a noticeboard entry' );
2024-02-23 22:49:23 +01:00
2012-08-27 18:24:29 +02:00
if ( $config [ 'cache' ][ 'enabled' ])
cache :: delete ( 'noticeboard_preview' );
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
header ( 'Location: ?/noticeboard' , true , $config [ 'redirect_http' ]);
}
2024-08-15 17:05:43 +02:00
function mod_news ( Context $ctx , $page_no = 1 ) {
2024-08-15 17:12:14 +02:00
global $pdo , $mod ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( $page_no < 1 )
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( isset ( $_POST [ 'subject' ], $_POST [ 'body' ])) {
if ( ! hasPermission ( $config [ 'mod' ][ 'news' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 00:59:54 +02:00
$_POST [ 'body' ] = escape_markup_modifiers ( $_POST [ 'body' ]);
2012-05-05 17:33:10 +02:00
markup ( $_POST [ 'body' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( 'INSERT INTO ``news`` VALUES (NULL, :name, :time, :subject, :body)' );
2012-05-05 17:33:10 +02:00
$query -> bindValue ( ':name' , isset ( $_POST [ 'name' ]) && hasPermission ( $config [ 'mod' ][ 'news_custom' ]) ? $_POST [ 'name' ] : $mod [ 'username' ]);
$query -> bindvalue ( ':time' , time ());
$query -> bindValue ( ':subject' , $_POST [ 'subject' ]);
$query -> bindValue ( ':body' , $_POST [ 'body' ]);
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
modLog ( 'Posted a news entry' );
2024-02-23 22:49:23 +01:00
2024-08-16 18:32:32 +02:00
Vichan\Functions\Theme\rebuild_themes ( 'news' );
2024-02-23 22:49:23 +01:00
2014-12-14 12:27:26 +01:00
header ( 'Location: ?/edit_news#' . $pdo -> lastInsertId (), true , $config [ 'redirect_http' ]);
2012-05-05 17:33:10 +02:00
}
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( " SELECT * FROM ``news`` ORDER BY `id` DESC LIMIT :offset, :limit " );
2012-05-05 17:33:10 +02:00
$query -> bindValue ( ':limit' , $config [ 'mod' ][ 'news_page' ], PDO :: PARAM_INT );
$query -> bindValue ( ':offset' , ( $page_no - 1 ) * $config [ 'mod' ][ 'news_page' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
$news = $query -> fetchAll ( PDO :: FETCH_ASSOC );
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( empty ( $news ) && $page_no > 1 )
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2013-09-23 08:48:56 +02:00
foreach ( $news as & $entry ) {
2014-12-14 12:27:26 +01:00
$entry [ 'delete_token' ] = make_secure_link_token ( 'edit_news/delete/' . $entry [ 'id' ]);
2013-09-23 08:48:56 +02:00
}
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( " SELECT COUNT(*) FROM ``news`` " );
2012-05-05 17:33:10 +02:00
$query -> execute () or error ( db_error ( $query ));
2013-08-01 02:51:43 +02:00
$count = $query -> fetchColumn ();
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'News' ), $config [ 'file_mod_news' ], array ( 'news' => $news , 'count' => $count , 'token' => make_secure_link_token ( 'edit_news' )));
2012-05-05 17:33:10 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_news_delete ( Context $ctx , $id ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'news_delete' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( 'DELETE FROM ``news`` WHERE `id` = :id' );
2012-05-05 17:33:10 +02:00
$query -> bindValue ( ':id' , $id );
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
modLog ( 'Deleted a news entry' );
2024-02-23 22:49:23 +01:00
2014-12-14 12:27:26 +01:00
header ( 'Location: ?/edit_news' , true , $config [ 'redirect_http' ]);
2012-05-05 17:33:10 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_log ( Context $ctx , $page_no = 1 ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-21 07:29:57 +02:00
if ( $page_no < 1 )
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2012-04-13 02:41:30 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'modlog' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( " SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM ``modlogs`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` ORDER BY `time` DESC LIMIT :offset, :limit " );
2012-04-13 02:41:30 +02:00
$query -> bindValue ( ':limit' , $config [ 'mod' ][ 'modlog_page' ], PDO :: PARAM_INT );
$query -> bindValue ( ':offset' , ( $page_no - 1 ) * $config [ 'mod' ][ 'modlog_page' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
$logs = $query -> fetchAll ( PDO :: FETCH_ASSOC );
2024-02-23 22:49:23 +01:00
2012-04-21 07:29:57 +02:00
if ( empty ( $logs ) && $page_no > 1 )
2012-04-21 07:15:32 +02:00
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( " SELECT COUNT(*) FROM ``modlogs`` " );
2012-04-13 12:57:59 +02:00
$query -> execute () or error ( db_error ( $query ));
2013-08-01 02:51:43 +02:00
$count = $query -> fetchColumn ();
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Moderation log' ), $config [ 'file_mod_log' ], array ( 'logs' => $logs , 'count' => $count ));
2012-04-13 02:41:30 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_user_log ( Context $ctx , $username , $page_no = 1 ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-08-27 14:13:47 +02:00
if ( $page_no < 1 )
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2012-08-27 14:13:47 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'modlog' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( " SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM ``modlogs`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` WHERE `username` = :username ORDER BY `time` DESC LIMIT :offset, :limit " );
2012-08-27 14:13:47 +02:00
$query -> bindValue ( ':username' , $username );
$query -> bindValue ( ':limit' , $config [ 'mod' ][ 'modlog_page' ], PDO :: PARAM_INT );
$query -> bindValue ( ':offset' , ( $page_no - 1 ) * $config [ 'mod' ][ 'modlog_page' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
$logs = $query -> fetchAll ( PDO :: FETCH_ASSOC );
2024-02-23 22:49:23 +01:00
2012-08-27 14:13:47 +02:00
if ( empty ( $logs ) && $page_no > 1 )
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( " SELECT COUNT(*) FROM ``modlogs`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` WHERE `username` = :username " );
2012-08-27 14:15:58 +02:00
$query -> bindValue ( ':username' , $username );
2012-08-27 14:13:47 +02:00
$query -> execute () or error ( db_error ( $query ));
2013-08-01 02:51:43 +02:00
$count = $query -> fetchColumn ();
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Moderation log' ), $config [ 'file_mod_log' ], array ( 'logs' => $logs , 'count' => $count , 'username' => $username ));
2012-08-27 14:13:47 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_board_log ( Context $ctx , $board , $page_no = 1 , $hide_names = false , $public = false ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2015-02-26 02:21:49 +01:00
if ( $page_no < 1 )
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2015-02-26 02:21:49 +01:00
if ( ! hasPermission ( $config [ 'mod' ][ 'mod_board_log' ], $board ) && ! $public )
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2015-02-26 02:21:49 +01:00
$query = prepare ( " SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM ``modlogs`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` WHERE `board` = :board ORDER BY `time` DESC LIMIT :offset, :limit " );
$query -> bindValue ( ':board' , $board );
$query -> bindValue ( ':limit' , $config [ 'mod' ][ 'modlog_page' ], PDO :: PARAM_INT );
$query -> bindValue ( ':offset' , ( $page_no - 1 ) * $config [ 'mod' ][ 'modlog_page' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
$logs = $query -> fetchAll ( PDO :: FETCH_ASSOC );
2024-02-23 22:49:23 +01:00
2015-02-26 02:21:49 +01:00
if ( empty ( $logs ) && $page_no > 1 )
error ( $config [ 'error' ][ '404' ]);
if ( ! hasPermission ( $config [ 'mod' ][ 'show_ip' ])) {
// Supports ipv4 only!
foreach ( $logs as $i => & $log ) {
$log [ 'text' ] = preg_replace_callback ( '/(?:<a href="\?\/IP\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}">)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?:<\/a>)?/' , function ( $matches ) {
return " xxxx " ; //less_ip($matches[1]);
}, $log [ 'text' ]);
}
}
2024-02-23 22:49:23 +01:00
2015-02-26 02:21:49 +01:00
$query = prepare ( " SELECT COUNT(*) FROM ``modlogs`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` WHERE `board` = :board " );
$query -> bindValue ( ':board' , $board );
$query -> execute () or error ( db_error ( $query ));
$count = $query -> fetchColumn ();
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Board log' ), $config [ 'file_mod_log' ], array ( 'logs' => $logs , 'count' => $count , 'board' => $board , 'hide_names' => $hide_names , 'public' => $public ));
2015-02-26 02:21:49 +01:00
}
2024-08-15 17:05:43 +02:00
function mod_view_catalog ( Context $ctx , $boardName ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2022-06-20 20:09:55 +02:00
require_once ( $config [ 'dir' ][ 'themes' ] . '/catalog/theme.php' );
2024-08-15 17:21:41 +02:00
$settings = [];
2022-06-20 20:09:55 +02:00
$settings [ 'boards' ] = $boardName ;
$settings [ 'update_on_posts' ] = true ;
$settings [ 'title' ] = 'Catalog' ;
$settings [ 'use_tooltipster' ] = true ;
$catalog = new Catalog ();
echo $catalog -> build ( $settings , $boardName , true );
}
2024-08-15 17:05:43 +02:00
function mod_view_board ( Context $ctx , $boardName , $page_no = 1 ) {
2024-08-15 17:12:14 +02:00
global $mod ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-12 18:11:41 +02:00
if ( ! openBoard ( $boardName ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2012-04-12 18:11:41 +02:00
if ( ! $page = index ( $page_no , $mod )) {
error ( $config [ 'error' ][ '404' ]);
}
2024-02-23 22:49:23 +01:00
2012-04-12 18:11:41 +02:00
$page [ 'pages' ] = getPages ( true );
$page [ 'pages' ][ $page_no - 1 ][ 'selected' ] = true ;
$page [ 'btn' ] = getPageButtons ( $page [ 'pages' ], true );
$page [ 'mod' ] = true ;
$page [ 'config' ] = $config ;
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
echo Element ( $config [ 'file_board_index' ], $page );
2012-04-12 18:11:41 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_view_thread ( Context $ctx , $boardName , $thread ) {
2024-08-15 17:12:14 +02:00
global $mod ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-12 18:11:41 +02:00
if ( ! openBoard ( $boardName ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2012-04-12 18:11:41 +02:00
$page = buildThread ( $thread , true , $mod );
echo $page ;
}
2024-08-15 17:05:43 +02:00
function mod_view_thread50 ( Context $ctx , $boardName , $thread ) {
2024-08-15 17:12:14 +02:00
global $mod ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2013-08-10 23:16:30 +02:00
if ( ! openBoard ( $boardName ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2013-08-10 23:16:30 +02:00
$page = buildThread50 ( $thread , true , $mod );
echo $page ;
}
2024-08-15 17:05:43 +02:00
function mod_ip_remove_note ( Context $ctx , $cloaked_ip , $id ) {
2021-02-13 14:11:41 +01:00
$ip = uncloak_ip ( $cloaked_ip );
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-14 14:58:36 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'remove_notes' ]))
2024-08-15 17:12:14 +02:00
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2014-07-08 09:44:30 +02:00
if ( filter_var ( $ip , FILTER_VALIDATE_IP ) === false )
error ( " Invalid IP address. " );
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( 'DELETE FROM ``ip_notes`` WHERE `ip` = :ip AND `id` = :id' );
2012-04-13 02:41:30 +02:00
$query -> bindValue ( ':ip' , $ip );
$query -> bindValue ( ':id' , $id );
$query -> execute () or error ( db_error ( $query ));
2021-02-13 14:11:41 +01:00
modLog ( " Removed a note for <a href= \" ?/IP/ { $cloaked_ip } \" > { $cloaked_ip } </a> " );
2024-02-23 22:49:23 +01:00
2021-02-13 14:11:41 +01:00
header ( 'Location: ?/IP/' . $cloaked_ip . '#notes' , true , $config [ 'redirect_http' ]);
2012-04-13 02:41:30 +02:00
}
2021-03-12 21:51:42 +01:00
2024-08-15 17:05:43 +02:00
function mod_ip ( Context $ctx , $cip ) {
2021-02-13 14:11:41 +01:00
$ip = uncloak_ip ( $cip );
2024-08-15 17:12:14 +02:00
global $mod ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2014-07-08 09:44:30 +02:00
if ( filter_var ( $ip , FILTER_VALIDATE_IP ) === false )
error ( " Invalid IP address. " );
2024-02-23 22:49:23 +01:00
2012-04-13 01:47:27 +02:00
if ( isset ( $_POST [ 'ban_id' ], $_POST [ 'unban' ])) {
2012-04-14 14:58:36 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'unban' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2014-10-08 23:23:59 +02:00
Bans :: delete ( $_POST [ 'ban_id' ], true , $mod [ 'boards' ]);
2024-02-23 22:49:23 +01:00
2021-02-13 14:11:41 +01:00
header ( 'Location: ?/IP/' . $cip . '#bans' , true , $config [ 'redirect_http' ]);
2012-04-13 01:47:27 +02:00
return ;
}
2023-01-13 02:38:23 +01:00
if ( isset ( $_POST [ 'ban_id' ], $_POST [ 'edit_ban' ])) {
if ( ! hasPermission ( $config [ 'mod' ][ 'edit_ban' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
header ( 'Location: ?/edit_ban/' . $_POST [ 'ban_id' ], true , $config [ 'redirect_http' ]);
return ;
}
2024-02-23 22:49:23 +01:00
2012-04-13 02:41:30 +02:00
if ( isset ( $_POST [ 'note' ])) {
2012-04-14 14:58:36 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'create_notes' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 00:59:54 +02:00
$_POST [ 'note' ] = escape_markup_modifiers ( $_POST [ 'note' ]);
2012-04-13 02:41:30 +02:00
markup ( $_POST [ 'note' ]);
2013-08-01 04:14:26 +02:00
$query = prepare ( 'INSERT INTO ``ip_notes`` VALUES (NULL, :ip, :mod, :time, :body)' );
2012-04-13 02:41:30 +02:00
$query -> bindValue ( ':ip' , $ip );
$query -> bindValue ( ':mod' , $mod [ 'id' ]);
$query -> bindValue ( ':time' , time ());
$query -> bindValue ( ':body' , $_POST [ 'note' ]);
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2021-02-13 14:11:41 +01:00
modLog ( " Added a note for <a href= \" ?/IP/ { $cip } \" > { $cip } </a> " );
2024-02-23 22:49:23 +01:00
2021-02-13 14:11:41 +01:00
header ( 'Location: ?/IP/' . $cip . '#notes' , true , $config [ 'redirect_http' ]);
2012-04-13 02:41:30 +02:00
return ;
}
2021-03-12 21:51:42 +01:00
2024-08-15 17:21:41 +02:00
$args = [];
2012-04-12 18:11:41 +02:00
$args [ 'ip' ] = $ip ;
2024-08-15 17:21:41 +02:00
$args [ 'posts' ] = [];
2024-02-23 22:49:23 +01:00
2021-02-13 14:11:41 +01:00
if ( $config [ 'mod' ][ 'dns_lookup' ] && empty ( $config [ 'ipcrypt_key' ]))
2012-05-05 17:33:10 +02:00
$args [ 'hostname' ] = rDNS ( $ip );
2024-02-23 22:49:23 +01:00
2012-04-12 18:11:41 +02:00
$boards = listBoards ();
foreach ( $boards as $board ) {
2012-04-13 01:29:08 +02:00
openBoard ( $board [ 'uri' ]);
2013-07-31 05:30:49 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'show_ip' ], $board [ 'uri' ]))
continue ;
2014-07-08 09:44:30 +02:00
$query = prepare ( sprintf ( 'SELECT * FROM ``posts_%s`` WHERE `ip` = :ip ORDER BY `sticky` DESC, `id` DESC LIMIT :limit' , $board [ 'uri' ]));
2012-04-12 18:11:41 +02:00
$query -> bindValue ( ':ip' , $ip );
$query -> bindValue ( ':limit' , $config [ 'mod' ][ 'ip_recentposts' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-04-16 08:40:24 +02:00
while ( $post = $query -> fetch ( PDO :: FETCH_ASSOC )) {
2012-04-12 18:11:41 +02:00
if ( ! $post [ 'thread' ]) {
2013-08-16 13:08:01 +02:00
$po = new Thread ( $post , '?/' , $mod , false );
2012-04-12 18:11:41 +02:00
} else {
2013-08-16 13:08:01 +02:00
$po = new Post ( $post , '?/' , $mod );
2012-04-12 18:11:41 +02:00
}
2024-02-23 22:49:23 +01:00
2012-04-12 18:11:41 +02:00
if ( ! isset ( $args [ 'posts' ][ $board [ 'uri' ]]))
2024-08-15 17:21:41 +02:00
$args [ 'posts' ][ $board [ 'uri' ]] = array ( 'board' => $board , 'posts' => []);
2012-04-13 01:29:08 +02:00
$args [ 'posts' ][ $board [ 'uri' ]][ 'posts' ][] = $po -> build ( true );
2012-04-12 18:11:41 +02:00
}
}
2024-02-23 22:49:23 +01:00
2012-04-13 01:29:08 +02:00
$args [ 'boards' ] = $boards ;
2012-08-27 18:24:29 +02:00
$args [ 'token' ] = make_secure_link_token ( 'ban' );
2024-02-23 22:49:23 +01:00
2012-04-14 14:28:21 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'view_ban' ])) {
2024-06-30 16:48:22 +02:00
$args [ 'bans' ] = Bans :: find ( $ip , false , true , null , $config [ 'auto_maintenance' ]);
2012-04-14 14:28:21 +02:00
}
2024-02-23 22:49:23 +01:00
2012-04-14 14:28:21 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'view_notes' ])) {
2013-08-03 08:06:58 +02:00
$query = prepare ( " SELECT ``ip_notes``.*, `username` FROM ``ip_notes`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` WHERE `ip` = :ip ORDER BY `time` DESC " );
2012-04-14 14:28:21 +02:00
$query -> bindValue ( ':ip' , $ip );
$query -> execute () or error ( db_error ( $query ));
$args [ 'notes' ] = $query -> fetchAll ( PDO :: FETCH_ASSOC );
}
2021-03-12 21:51:42 +01:00
2013-03-16 08:27:24 +01:00
if ( hasPermission ( $config [ 'mod' ][ 'modlog_ip' ])) {
2013-08-03 08:06:58 +02:00
$query = prepare ( " SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM ``modlogs`` LEFT JOIN ``mods`` ON `mod` = ``mods``.`id` WHERE `text` LIKE :search ORDER BY `time` DESC LIMIT 50 " );
2021-02-13 14:11:41 +01:00
$query -> bindValue ( ':search' , '%' . $cip . '%' );
2013-03-16 08:27:24 +01:00
$query -> execute () or error ( db_error ( $query ));
$args [ 'logs' ] = $query -> fetchAll ( PDO :: FETCH_ASSOC );
} else {
2024-08-15 17:21:41 +02:00
$args [ 'logs' ] = [];
2013-03-16 08:27:24 +01:00
}
2024-02-23 22:49:23 +01:00
2021-02-13 14:11:41 +01:00
$args [ 'security_token' ] = make_secure_link_token ( 'IP/' . $cip );
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( sprintf ( '%s: %s' , _ ( 'IP' ), htmlspecialchars ( $cip )), $config [ 'file_mod_view_ip' ], $args , $args [ 'hostname' ]);
2012-04-12 18:11:41 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_edit_ban ( Context $ctx , $ban_id ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2023-01-13 02:38:23 +01:00
if ( ! hasPermission ( $config [ 'mod' ][ 'edit_ban' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-06-30 16:48:22 +02:00
$args [ 'bans' ] = Bans :: find ( null , false , true , $ban_id , $config [ 'auto_maintenance' ]);
2023-01-13 02:38:23 +01:00
$args [ 'ban_id' ] = $ban_id ;
$args [ 'boards' ] = listBoards ();
$args [ 'current_board' ] = isset ( $args [ 'bans' ][ 0 ][ 'board' ]) ? $args [ 'bans' ][ 0 ][ 'board' ] : false ;
if ( ! $args [ 'bans' ])
error ( $config [ 'error' ][ '404' ]);
if ( isset ( $_POST [ 'new_ban' ])) {
$new_ban [ 'mask' ] = $args [ 'bans' ][ 0 ][ 'mask' ];
$new_ban [ 'post' ] = isset ( $args [ 'bans' ][ 0 ][ 'post' ]) ? $args [ 'bans' ][ 0 ][ 'post' ] : false ;
$new_ban [ 'board' ] = $args [ 'current_board' ];
if ( isset ( $_POST [ 'reason' ]))
$new_ban [ 'reason' ] = $_POST [ 'reason' ];
else
$new_ban [ 'reason' ] = $args [ 'bans' ][ 0 ][ 'reason' ];
2023-01-13 13:22:53 +01:00
if ( isset ( $_POST [ 'length' ]) && ! empty ( $_POST [ 'length' ]))
$new_ban [ 'length' ] = $_POST [ 'length' ];
2023-01-13 02:38:23 +01:00
else
$new_ban [ 'length' ] = false ;
if ( isset ( $_POST [ 'board' ])) {
if ( $_POST [ 'board' ] == '*' )
$new_ban [ 'board' ] = false ;
else
$new_ban [ 'board' ] = $_POST [ 'board' ];
}
Bans :: new_ban ( $new_ban [ 'mask' ], $new_ban [ 'reason' ], $new_ban [ 'length' ], $new_ban [ 'board' ], false , $new_ban [ 'post' ]);
Bans :: delete ( $ban_id );
header ( 'Location: ?/' , true , $config [ 'redirect_http' ]);
}
$args [ 'token' ] = make_secure_link_token ( 'edit_ban/' . $ban_id );
mod_page ( _ ( 'Edit ban' ), 'mod/edit_ban.html' , $args );
}
2024-08-15 17:05:43 +02:00
function mod_ban ( Context $ctx ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-14 14:28:21 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'ban' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2012-04-13 02:41:30 +02:00
if ( ! isset ( $_POST [ 'ip' ], $_POST [ 'reason' ], $_POST [ 'length' ], $_POST [ 'board' ])) {
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'New ban' ), $config [ 'file_mod_ban_form' ], array ( 'token' => make_secure_link_token ( 'ban' )));
2012-04-13 02:41:30 +02:00
return ;
}
2024-02-14 11:07:47 +01:00
2013-09-17 01:15:24 +02:00
Bans :: new_ban ( $_POST [ 'ip' ], $_POST [ 'reason' ], $_POST [ 'length' ], $_POST [ 'board' ] == '*' ? false : $_POST [ 'board' ]);
2014-10-08 23:23:59 +02:00
2012-04-13 01:47:27 +02:00
if ( isset ( $_POST [ 'redirect' ]))
2012-04-13 01:29:08 +02:00
header ( 'Location: ' . $_POST [ 'redirect' ], true , $config [ 'redirect_http' ]);
else
header ( 'Location: ?/' , true , $config [ 'redirect_http' ]);
}
2024-08-15 17:05:43 +02:00
function mod_bans ( Context $ctx ) {
2014-10-08 23:23:59 +02:00
global $mod ;
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-16 08:40:24 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'view_banlist' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2012-04-16 08:40:24 +02:00
if ( isset ( $_POST [ 'unban' ])) {
if ( ! hasPermission ( $config [ 'mod' ][ 'unban' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2024-08-15 17:21:41 +02:00
$unban = [];
2012-04-16 08:40:24 +02:00
foreach ( $_POST as $name => $unused ) {
if ( preg_match ( '/^ban_(\d+)$/' , $name , $match ))
$unban [] = $match [ 1 ];
}
2013-09-17 01:15:24 +02:00
if ( isset ( $config [ 'mod' ][ 'unban_limit' ]) && $config [ 'mod' ][ 'unban_limit' ] && count ( $unban ) > $config [ 'mod' ][ 'unban_limit' ])
error ( sprintf ( $config [ 'error' ][ 'toomanyunban' ], $config [ 'mod' ][ 'unban_limit' ], count ( $unban )));
2024-02-23 22:49:23 +01:00
2013-09-17 01:15:24 +02:00
foreach ( $unban as $id ) {
2014-10-08 23:23:59 +02:00
Bans :: delete ( $id , true , $mod [ 'boards' ], true );
2013-04-17 00:09:58 +02:00
}
2024-08-16 18:32:32 +02:00
Vichan\Functions\Theme\rebuild_themes ( 'bans' );
2012-04-16 08:40:24 +02:00
header ( 'Location: ?/bans' , true , $config [ 'redirect_http' ]);
2013-09-17 01:15:24 +02:00
return ;
2012-04-16 08:40:24 +02:00
}
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Ban list' ), $config [ 'file_mod_ban_list' ], array (
2014-10-08 23:23:59 +02:00
'mod' => $mod ,
'boards' => json_encode ( $mod [ 'boards' ]),
'token' => make_secure_link_token ( 'bans' ),
'token_json' => make_secure_link_token ( 'bans.json' )
2013-09-23 08:48:56 +02:00
));
2012-04-16 08:40:24 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_bans_json ( Context $ctx ) {
2024-08-15 17:12:14 +02:00
global $mod ;
$config = $ctx -> get ( 'config' );
2014-10-08 23:23:59 +02:00
2024-08-15 17:05:43 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'ban' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2014-10-08 23:23:59 +02:00
// Compress the json for faster loads
if ( substr_count ( $_SERVER [ 'HTTP_ACCEPT_ENCODING' ], 'gzip' )) ob_start ( " ob_gzhandler " );
Bans :: stream_json ( false , false , ! hasPermission ( $config [ 'mod' ][ 'view_banstaff' ]), $mod [ 'boards' ]);
}
2024-08-15 17:05:43 +02:00
function mod_ban_appeals ( Context $ctx ) {
2024-08-15 17:12:14 +02:00
global $board ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2013-09-21 04:51:23 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'view_ban_appeals' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-09-21 04:51:23 +02:00
if ( isset ( $_POST [ 'appeal_id' ]) && ( isset ( $_POST [ 'unban' ]) || isset ( $_POST [ 'deny' ]))) {
if ( ! hasPermission ( $config [ 'mod' ][ 'ban_appeals' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-09-23 08:48:56 +02:00
$query = query ( " SELECT *, ``ban_appeals``.`id` AS `id` FROM ``ban_appeals``
LEFT JOIN `` bans `` ON `ban_id` = `` bans `` . `id`
WHERE `` ban_appeals `` . `id` = " . (int) $_POST['appeal_id'] ) or error(db_error());
if ( ! $ban = $query -> fetch ( PDO :: FETCH_ASSOC )) {
error ( _ ( 'Ban appeal not found!' ));
}
2024-02-23 22:49:23 +01:00
2021-02-13 14:11:41 +01:00
$ban [ 'mask' ] = cloak_mask ( Bans :: range_to_string ( array ( $ban [ 'ipstart' ], $ban [ 'ipend' ])));
2024-02-23 22:49:23 +01:00
2013-09-21 04:51:23 +02:00
if ( isset ( $_POST [ 'unban' ])) {
2013-09-23 08:48:56 +02:00
modLog ( 'Accepted ban appeal #' . $ban [ 'id' ] . ' for ' . $ban [ 'mask' ]);
Bans :: delete ( $ban [ 'ban_id' ], true );
query ( " DELETE FROM ``ban_appeals`` WHERE `id` = " . $ban [ 'id' ]) or error ( db_error ());
2013-09-21 04:51:23 +02:00
} else {
2013-09-23 08:48:56 +02:00
modLog ( 'Denied ban appeal #' . $ban [ 'id' ] . ' for ' . $ban [ 'mask' ]);
query ( " UPDATE ``ban_appeals`` SET `denied` = 1 WHERE `id` = " . $ban [ 'id' ]) or error ( db_error ());
2013-09-21 04:51:23 +02:00
}
2024-02-23 22:49:23 +01:00
2013-09-21 04:51:23 +02:00
header ( 'Location: ?/ban-appeals' , true , $config [ 'redirect_http' ]);
return ;
}
2024-02-23 22:49:23 +01:00
2013-09-21 04:51:23 +02:00
$query = query ( " SELECT *, ``ban_appeals``.`id` AS `id` FROM ``ban_appeals``
LEFT JOIN `` bans `` ON `ban_id` = `` bans `` . `id`
2014-09-01 00:30:33 +02:00
LEFT JOIN `` mods `` ON `` bans `` . `creator` = `` mods `` . `id`
2013-09-21 04:51:23 +02:00
WHERE `denied` != 1 ORDER BY `time` " ) or error(db_error());
$ban_appeals = $query -> fetchAll ( PDO :: FETCH_ASSOC );
foreach ( $ban_appeals as & $ban ) {
if ( $ban [ 'post' ])
$ban [ 'post' ] = json_decode ( $ban [ 'post' ], true );
$ban [ 'mask' ] = Bans :: range_to_string ( array ( $ban [ 'ipstart' ], $ban [ 'ipend' ]));
2024-02-23 22:49:23 +01:00
2013-09-21 04:51:23 +02:00
if ( $ban [ 'post' ] && isset ( $ban [ 'post' ][ 'board' ], $ban [ 'post' ][ 'id' ])) {
if ( openBoard ( $ban [ 'post' ][ 'board' ])) {
2014-06-16 11:39:56 +02:00
$query = query ( sprintf ( " SELECT `num_files`, `files` FROM ``posts_%s`` WHERE `id` = " .
2013-09-21 04:51:23 +02:00
( int ) $ban [ 'post' ][ 'id' ], $board [ 'uri' ]));
if ( $_post = $query -> fetch ( PDO :: FETCH_ASSOC )) {
2024-08-15 17:21:41 +02:00
$_post [ 'files' ] = $_post [ 'files' ] ? json_decode ( $_post [ 'files' ]) : [];
2013-09-21 04:51:23 +02:00
$ban [ 'post' ] = array_merge ( $ban [ 'post' ], $_post );
} else {
2024-08-15 17:21:41 +02:00
$ban [ 'post' ][ 'files' ] = array ([]);
2014-06-16 11:39:56 +02:00
$ban [ 'post' ][ 'files' ][ 0 ][ 'file' ] = 'deleted' ;
$ban [ 'post' ][ 'files' ][ 0 ][ 'thumb' ] = false ;
$ban [ 'post' ][ 'num_files' ] = 1 ;
2013-09-21 04:51:23 +02:00
}
} else {
2024-08-15 17:21:41 +02:00
$ban [ 'post' ][ 'files' ] = array ([]);
2014-06-16 11:39:56 +02:00
$ban [ 'post' ][ 'files' ][ 0 ][ 'file' ] = 'deleted' ;
$ban [ 'post' ][ 'files' ][ 0 ][ 'thumb' ] = false ;
$ban [ 'post' ][ 'num_files' ] = 1 ;
2013-09-21 04:51:23 +02:00
}
2024-02-23 22:49:23 +01:00
2013-09-21 04:51:23 +02:00
if ( $ban [ 'post' ][ 'thread' ]) {
$ban [ 'post' ] = new Post ( $ban [ 'post' ]);
} else {
$ban [ 'post' ] = new Thread ( $ban [ 'post' ], null , false , false );
}
}
}
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Ban appeals' ), $config [ 'file_mod_ban_appeals' ], array (
2013-09-23 08:48:56 +02:00
'ban_appeals' => $ban_appeals ,
'token' => make_secure_link_token ( 'ban-appeals' )
));
2013-09-21 04:51:23 +02:00
}
2012-04-16 12:11:10 +02:00
2024-08-15 17:05:43 +02:00
function mod_lock ( Context $ctx , $board , $unlock , $post ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-16 12:11:10 +02:00
if ( ! openBoard ( $board ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2012-04-16 12:11:10 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'lock' ], $board ))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( sprintf ( 'UPDATE ``posts_%s`` SET `locked` = :locked WHERE `id` = :id AND `thread` IS NULL' , $board ));
2012-04-16 12:11:10 +02:00
$query -> bindValue ( ':id' , $post );
$query -> bindValue ( ':locked' , $unlock ? 0 : 1 );
$query -> execute () or error ( db_error ( $query ));
2012-05-05 17:33:10 +02:00
if ( $query -> rowCount ()) {
2012-04-16 15:18:07 +02:00
modLog (( $unlock ? 'Unlocked' : 'Locked' ) . " thread # { $post } " );
2012-04-16 12:14:57 +02:00
buildThread ( $post );
buildIndex ();
}
2024-02-23 22:49:23 +01:00
2013-07-16 08:32:44 +02:00
if ( $config [ 'mod' ][ 'dismiss_reports_on_lock' ]) {
2013-08-01 04:14:26 +02:00
$query = prepare ( 'DELETE FROM ``reports`` WHERE `board` = :board AND `post` = :id' );
2013-07-16 08:32:44 +02:00
$query -> bindValue ( ':board' , $board );
$query -> bindValue ( ':id' , $post );
$query -> execute () or error ( db_error ( $query ));
}
2024-02-23 22:49:23 +01:00
2012-04-16 12:11:10 +02:00
header ( 'Location: ?/' . sprintf ( $config [ 'board_path' ], $board ) . $config [ 'file_index' ], true , $config [ 'redirect_http' ]);
2024-02-23 22:49:23 +01:00
2012-11-19 00:28:23 +01:00
if ( $unlock )
event ( 'unlock' , $post );
else
event ( 'lock' , $post );
2012-04-16 12:11:10 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_sticky ( Context $ctx , $board , $unsticky , $post ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-16 12:11:10 +02:00
if ( ! openBoard ( $board ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2012-04-16 12:11:10 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'sticky' ], $board ))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( sprintf ( 'UPDATE ``posts_%s`` SET `sticky` = :sticky WHERE `id` = :id AND `thread` IS NULL' , $board ));
2012-04-16 12:11:10 +02:00
$query -> bindValue ( ':id' , $post );
$query -> bindValue ( ':sticky' , $unsticky ? 0 : 1 );
$query -> execute () or error ( db_error ( $query ));
2012-05-05 17:33:10 +02:00
if ( $query -> rowCount ()) {
2012-07-12 15:43:43 +02:00
modLog (( $unsticky ? 'Unstickied' : 'Stickied' ) . " thread # { $post } " );
2012-04-16 12:14:57 +02:00
buildThread ( $post );
buildIndex ();
}
2024-02-23 22:49:23 +01:00
2012-04-16 12:11:10 +02:00
header ( 'Location: ?/' . sprintf ( $config [ 'board_path' ], $board ) . $config [ 'file_index' ], true , $config [ 'redirect_http' ]);
}
2024-08-15 17:05:43 +02:00
function mod_cycle ( Context $ctx , $board , $uncycle , $post ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2015-04-03 08:56:28 +02:00
if ( ! openBoard ( $board ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2015-04-03 08:56:28 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'cycle' ], $board ))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2015-04-03 08:56:28 +02:00
$query = prepare ( sprintf ( 'UPDATE ``posts_%s`` SET `cycle` = :cycle WHERE `id` = :id AND `thread` IS NULL' , $board ));
$query -> bindValue ( ':id' , $post );
$query -> bindValue ( ':cycle' , $uncycle ? 0 : 1 );
$query -> execute () or error ( db_error ( $query ));
if ( $query -> rowCount ()) {
modLog (( $uncycle ? 'Made not cyclical' : 'Made cyclical' ) . " thread # { $post } " );
buildThread ( $post );
buildIndex ();
}
2024-02-23 22:49:23 +01:00
2015-04-03 08:56:28 +02:00
header ( 'Location: ?/' . sprintf ( $config [ 'board_path' ], $board ) . $config [ 'file_index' ], true , $config [ 'redirect_http' ]);
}
2024-08-15 17:05:43 +02:00
function mod_bumplock ( Context $ctx , $board , $unbumplock , $post ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-16 12:11:10 +02:00
if ( ! openBoard ( $board ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2012-04-16 12:11:10 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'bumplock' ], $board ))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( sprintf ( 'UPDATE ``posts_%s`` SET `sage` = :bumplock WHERE `id` = :id AND `thread` IS NULL' , $board ));
2012-04-16 12:11:10 +02:00
$query -> bindValue ( ':id' , $post );
$query -> bindValue ( ':bumplock' , $unbumplock ? 0 : 1 );
$query -> execute () or error ( db_error ( $query ));
2012-05-05 17:33:10 +02:00
if ( $query -> rowCount ()) {
2012-07-12 15:43:43 +02:00
modLog (( $unbumplock ? 'Unbumplocked' : 'Bumplocked' ) . " thread # { $post } " );
2012-04-16 12:14:57 +02:00
buildThread ( $post );
buildIndex ();
}
2024-02-23 22:49:23 +01:00
2012-04-16 12:11:10 +02:00
header ( 'Location: ?/' . sprintf ( $config [ 'board_path' ], $board ) . $config [ 'file_index' ], true , $config [ 'redirect_http' ]);
}
2024-08-15 17:05:43 +02:00
function mod_move_reply ( Context $ctx , $originBoard , $postID ) {
global $board , $config ;
2013-08-08 23:08:01 +02:00
if ( ! openBoard ( $originBoard ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2013-08-08 23:08:01 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'move' ], $originBoard ))
error ( $config [ 'error' ][ 'noaccess' ]);
2013-08-09 23:42:19 +02:00
$query = prepare ( sprintf ( 'SELECT * FROM ``posts_%s`` WHERE `id` = :id' , $originBoard ));
2013-08-08 23:08:01 +02:00
$query -> bindValue ( ':id' , $postID );
$query -> execute () or error ( db_error ( $query ));
if ( ! $post = $query -> fetch ( PDO :: FETCH_ASSOC ))
error ( $config [ 'error' ][ '404' ]);
if ( isset ( $_POST [ 'board' ])) {
$targetBoard = $_POST [ 'board' ];
if ( $_POST [ 'target_thread' ]) {
2013-08-09 23:42:19 +02:00
$query = prepare ( sprintf ( 'SELECT * FROM ``posts_%s`` WHERE `id` = :id' , $targetBoard ));
2013-08-08 23:08:01 +02:00
$query -> bindValue ( ':id' , $_POST [ 'target_thread' ]);
$query -> execute () or error ( db_error ( $query )); // If it fails, thread probably does not exist
$post [ 'op' ] = false ;
$post [ 'thread' ] = $_POST [ 'target_thread' ];
}
else {
$post [ 'op' ] = true ;
}
2024-02-23 22:49:23 +01:00
2014-04-30 01:14:10 +02:00
if ( $post [ 'files' ]) {
$post [ 'files' ] = json_decode ( $post [ 'files' ], TRUE );
2013-08-08 23:08:01 +02:00
$post [ 'has_file' ] = true ;
2014-04-30 01:14:10 +02:00
foreach ( $post [ 'files' ] as $i => & $file ) {
$file [ 'file_path' ] = sprintf ( $config [ 'board_path' ], $board [ 'uri' ]) . $config [ 'dir' ][ 'img' ] . $file [ 'file' ];
2024-02-23 22:49:23 +01:00
if ( isset ( $file [ 'thumb' ]))
2014-04-30 01:14:10 +02:00
$file [ 'thumb_path' ] = sprintf ( $config [ 'board_path' ], $board [ 'uri' ]) . $config [ 'dir' ][ 'thumb' ] . $file [ 'thumb' ];
}
2013-08-08 23:08:01 +02:00
} else {
$post [ 'has_file' ] = false ;
}
2024-02-23 22:49:23 +01:00
2013-08-08 23:08:01 +02:00
// allow thread to keep its same traits (stickied, locked, etc.)
$post [ 'mod' ] = true ;
2024-02-23 22:49:23 +01:00
2013-08-08 23:08:01 +02:00
if ( ! openBoard ( $targetBoard ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
// create the new post
2013-08-08 23:08:01 +02:00
$newID = post ( $post );
2024-02-23 22:49:23 +01:00
2013-08-08 23:08:01 +02:00
if ( $post [ 'has_file' ]) {
2014-04-30 01:14:10 +02:00
foreach ( $post [ 'files' ] as $i => & $file ) {
// move the image
2024-02-23 22:49:23 +01:00
if ( isset ( $file [ 'thumb' ]))
2017-07-28 22:41:20 +02:00
if ( $file [ 'thumb' ] != 'spoiler' || $file [ 'thumb' ] != 'deleted' ) { //trying to move/copy the spoiler thumb raises an error
2014-04-30 01:14:10 +02:00
rename ( $file [ 'file_path' ], sprintf ( $config [ 'board_path' ], $board [ 'uri' ]) . $config [ 'dir' ][ 'img' ] . $file [ 'file' ]);
2017-07-28 22:41:20 +02:00
rename ( $file [ 'thumb_path' ], sprintf ( $config [ 'board_path' ], $board [ 'uri' ]) . $config [ 'dir' ][ 'thumb' ] . $file [ 'thumb' ]);
2014-04-30 01:14:10 +02:00
}
2013-08-09 21:40:49 +02:00
}
2013-08-08 23:08:01 +02:00
}
2013-08-19 15:20:10 +02:00
// build index
2013-08-08 23:08:01 +02:00
buildIndex ();
2022-12-14 09:17:36 +01:00
// build new thread
buildThread ( $newID );
2024-02-23 22:49:23 +01:00
2013-08-08 23:08:01 +02:00
// trigger themes
2024-08-16 18:32:32 +02:00
Vichan\Functions\Theme\rebuild_themes ( 'post' , $targetBoard );
2013-08-08 23:08:01 +02:00
// mod log
2024-04-03 19:16:56 +02:00
modLog ( " Moved post # { $postID } to " . sprintf ( $config [ 'board_abbreviation' ], $targetBoard ) . " (# { $newID } ) " , $originBoard );
2024-02-23 22:49:23 +01:00
2013-08-08 23:08:01 +02:00
// return to original board
openBoard ( $originBoard );
// delete original post
deletePost ( $postID );
buildIndex ();
// open target board for redirect
openBoard ( $targetBoard );
// Find new thread on our target board
2013-08-09 23:42:19 +02:00
$query = prepare ( sprintf ( 'SELECT thread FROM ``posts_%s`` WHERE `id` = :id' , $targetBoard ));
2013-08-08 23:08:01 +02:00
$query -> bindValue ( ':id' , $newID );
$query -> execute () or error ( db_error ( $query ));
$post = $query -> fetch ( PDO :: FETCH_ASSOC );
// redirect
2015-03-10 12:48:59 +01:00
header ( 'Location: ?/' . sprintf ( $config [ 'board_path' ], $board [ 'uri' ]) . $config [ 'dir' ][ 'res' ] . link_for ( $post ) . '#' . $newID , true , $config [ 'redirect_http' ]);
2013-08-08 23:08:01 +02:00
}
else {
$boards = listBoards ();
2024-02-23 22:49:23 +01:00
2013-08-08 23:08:01 +02:00
$security_token = make_secure_link_token ( $originBoard . '/move_reply/' . $postID );
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Move reply' ), $config [ 'file_mod_move_reply' ], array ( 'post' => $postID , 'board' => $originBoard , 'boards' => $boards , 'token' => $security_token ));
2013-08-08 23:08:01 +02:00
}
}
2024-08-15 17:05:43 +02:00
function mod_move ( Context $ctx , $originBoard , $postID ) {
global $board , $config , $pdo ;
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
if ( ! openBoard ( $originBoard ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'move' ], $originBoard ))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( sprintf ( 'SELECT * FROM ``posts_%s`` WHERE `id` = :id AND `thread` IS NULL' , $originBoard ));
2012-05-19 10:27:45 +02:00
$query -> bindValue ( ':id' , $postID );
$query -> execute () or error ( db_error ( $query ));
if ( ! $post = $query -> fetch ( PDO :: FETCH_ASSOC ))
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
if ( isset ( $_POST [ 'board' ])) {
$targetBoard = $_POST [ 'board' ];
$shadow = isset ( $_POST [ 'shadow' ]);
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
if ( $targetBoard === $originBoard )
error ( _ ( 'Target and source board are the same.' ));
2024-02-23 22:49:23 +01:00
2024-05-22 23:54:06 +02:00
// link() if leaving a shadow thread behind; else, rename().
2024-08-18 01:06:45 +02:00
$clone = $shadow ? '_link_or_copy' : 'rename' ;
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
// indicate that the post is a thread
$post [ 'op' ] = true ;
2024-02-23 22:49:23 +01:00
2014-04-30 01:07:13 +02:00
if ( $post [ 'files' ]) {
$post [ 'files' ] = json_decode ( $post [ 'files' ], TRUE );
2012-05-19 10:27:45 +02:00
$post [ 'has_file' ] = true ;
2014-04-30 01:07:13 +02:00
foreach ( $post [ 'files' ] as $i => & $file ) {
2024-02-23 22:49:23 +01:00
if ( $file [ 'file' ] === 'deleted' )
2014-05-19 20:00:16 +02:00
continue ;
2014-04-30 01:07:13 +02:00
$file [ 'file_path' ] = sprintf ( $config [ 'board_path' ], $board [ 'uri' ]) . $config [ 'dir' ][ 'img' ] . $file [ 'file' ];
$file [ 'thumb_path' ] = sprintf ( $config [ 'board_path' ], $board [ 'uri' ]) . $config [ 'dir' ][ 'thumb' ] . $file [ 'thumb' ];
}
2012-05-19 10:27:45 +02:00
} else {
$post [ 'has_file' ] = false ;
}
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
// allow thread to keep its same traits (stickied, locked, etc.)
$post [ 'mod' ] = true ;
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
if ( ! openBoard ( $targetBoard ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
// create the new thread
$newID = post ( $post );
2024-02-23 22:49:23 +01:00
2015-03-10 13:46:34 +01:00
$op = $post ;
$op [ 'id' ] = $newID ;
2024-02-23 22:49:23 +01:00
2012-05-19 12:46:05 +02:00
if ( $post [ 'has_file' ]) {
2012-05-19 10:27:45 +02:00
// copy image
2014-04-30 01:07:13 +02:00
foreach ( $post [ 'files' ] as $i => & $file ) {
2024-02-23 22:49:23 +01:00
if ( $file [ 'file' ] !== 'deleted' )
2014-05-19 20:00:16 +02:00
$clone ( $file [ 'file_path' ], sprintf ( $config [ 'board_path' ], $board [ 'uri' ]) . $config [ 'dir' ][ 'img' ] . $file [ 'file' ]);
if ( isset ( $file [ 'thumb' ]) && ! in_array ( $file [ 'thumb' ], array ( 'spoiler' , 'deleted' , 'file' )))
2014-04-30 01:07:13 +02:00
$clone ( $file [ 'thumb_path' ], sprintf ( $config [ 'board_path' ], $board [ 'uri' ]) . $config [ 'dir' ][ 'thumb' ] . $file [ 'thumb' ]);
}
2012-05-19 10:27:45 +02:00
}
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
// go back to the original board to fetch replies
openBoard ( $originBoard );
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( sprintf ( 'SELECT * FROM ``posts_%s`` WHERE `thread` = :id ORDER BY `id`' , $originBoard ));
2012-05-19 10:27:45 +02:00
$query -> bindValue ( ':id' , $postID , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2024-08-15 17:21:41 +02:00
$replies = [];
2024-02-23 22:49:23 +01:00
2013-08-01 02:51:43 +02:00
while ( $post = $query -> fetch ( PDO :: FETCH_ASSOC )) {
2012-05-19 10:27:45 +02:00
$post [ 'mod' ] = true ;
$post [ 'thread' ] = $newID ;
2024-02-23 22:49:23 +01:00
2014-04-30 01:07:13 +02:00
if ( $post [ 'files' ]) {
$post [ 'files' ] = json_decode ( $post [ 'files' ], TRUE );
2012-05-19 10:27:45 +02:00
$post [ 'has_file' ] = true ;
2014-04-30 01:07:13 +02:00
foreach ( $post [ 'files' ] as $i => & $file ) {
$file [ 'file_path' ] = sprintf ( $config [ 'board_path' ], $board [ 'uri' ]) . $config [ 'dir' ][ 'img' ] . $file [ 'file' ];
2017-07-24 21:01:17 +02:00
2024-02-23 22:49:23 +01:00
if ( isset ( $file [ 'thumb' ]))
2017-07-24 21:01:17 +02:00
$file [ 'thumb_path' ] = sprintf ( $config [ 'board_path' ], $board [ 'uri' ]) . $config [ 'dir' ][ 'thumb' ] . $file [ 'thumb' ];
2014-04-30 01:07:13 +02:00
}
2012-05-19 10:27:45 +02:00
} else {
$post [ 'has_file' ] = false ;
}
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
$replies [] = $post ;
}
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
$newIDs = array ( $postID => $newID );
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
openBoard ( $targetBoard );
2024-02-23 22:49:23 +01:00
2012-05-19 12:46:05 +02:00
foreach ( $replies as & $post ) {
2013-08-01 04:14:26 +02:00
$query = prepare ( 'SELECT `target` FROM ``cites`` WHERE `target_board` = :board AND `board` = :board AND `post` = :post' );
2012-05-19 10:27:45 +02:00
$query -> bindValue ( ':board' , $originBoard );
$query -> bindValue ( ':post' , $post [ 'id' ], PDO :: PARAM_INT );
2016-08-20 20:31:19 +02:00
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
// correct >>X links
2012-05-19 12:46:05 +02:00
while ( $cite = $query -> fetch ( PDO :: FETCH_ASSOC )) {
if ( isset ( $newIDs [ $cite [ 'target' ]])) {
2012-05-19 10:27:45 +02:00
$post [ 'body_nomarkup' ] = preg_replace (
'/(>>(>\/' . preg_quote ( $originBoard , '/' ) . '\/)?)' . preg_quote ( $cite [ 'target' ], '/' ) . '/' ,
'>>' . $newIDs [ $cite [ 'target' ]],
$post [ 'body_nomarkup' ]);
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
$post [ 'body' ] = $post [ 'body_nomarkup' ];
}
}
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
$post [ 'body' ] = $post [ 'body_nomarkup' ];
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
$post [ 'op' ] = false ;
$post [ 'tracked_cites' ] = markup ( $post [ 'body' ], true );
2024-02-23 22:49:23 +01:00
2012-05-19 12:46:05 +02:00
if ( $post [ 'has_file' ]) {
2012-05-19 10:27:45 +02:00
// copy image
2014-04-30 01:07:13 +02:00
foreach ( $post [ 'files' ] as $i => & $file ) {
2024-02-23 22:49:23 +01:00
if ( isset ( $file [ 'thumb' ]))
2017-07-28 22:41:20 +02:00
if ( $file [ 'thumb' ] != 'spoiler' || $file [ 'thumb' ] != 'deleted' ) { //trying to move/copy the spoiler thumb raises an error
$clone ( $file [ 'file_path' ], sprintf ( $config [ 'board_path' ], $board [ 'uri' ]) . $config [ 'dir' ][ 'img' ] . $file [ 'file' ]);
$clone ( $file [ 'thumb_path' ], sprintf ( $config [ 'board_path' ], $board [ 'uri' ]) . $config [ 'dir' ][ 'thumb' ] . $file [ 'thumb' ]);
}
2014-04-30 01:07:13 +02:00
}
2012-05-19 10:27:45 +02:00
}
2014-04-30 01:07:13 +02:00
// insert reply
$newIDs [ $post [ 'id' ]] = $newPostID = post ( $post );
2024-02-23 22:49:23 +01:00
2013-08-30 07:00:33 +02:00
if ( ! empty ( $post [ 'tracked_cites' ])) {
2024-08-15 17:21:41 +02:00
$insert_rows = [];
2013-08-30 07:00:33 +02:00
foreach ( $post [ 'tracked_cites' ] as $cite ) {
$insert_rows [] = '(' .
$pdo -> quote ( $board [ 'uri' ]) . ', ' . $newPostID . ', ' .
$pdo -> quote ( $cite [ 0 ]) . ', ' . ( int ) $cite [ 1 ] . ')' ;
}
2013-08-31 05:33:26 +02:00
query ( 'INSERT INTO ``cites`` VALUES ' . implode ( ', ' , $insert_rows )) or error ( db_error ());
2012-05-19 10:27:45 +02:00
}
}
2024-02-23 22:49:23 +01:00
2024-04-03 19:16:56 +02:00
modLog ( " Moved thread # { $postID } to " . sprintf ( $config [ 'board_abbreviation' ], $targetBoard ) . " (# { $newID } ) " , $originBoard );
2024-02-23 22:49:23 +01:00
2013-07-16 07:38:24 +02:00
// build new thread
2012-05-19 10:27:45 +02:00
buildThread ( $newID );
2024-02-23 22:49:23 +01:00
2013-07-16 07:38:24 +02:00
clean ();
2012-05-19 10:27:45 +02:00
buildIndex ();
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
// trigger themes
2024-08-16 18:32:32 +02:00
Vichan\Functions\Theme\rebuild_themes ( 'post' , $targetBoard );
2024-02-23 22:49:23 +01:00
2015-03-10 12:48:59 +01:00
$newboard = $board ;
2012-05-19 10:27:45 +02:00
// return to original board
openBoard ( $originBoard );
2024-02-23 22:49:23 +01:00
2012-05-19 12:46:05 +02:00
if ( $shadow ) {
2012-05-19 10:27:45 +02:00
// lock old thread
2013-08-01 04:14:26 +02:00
$query = prepare ( sprintf ( 'UPDATE ``posts_%s`` SET `locked` = 1 WHERE `id` = :id' , $originBoard ));
2012-05-19 10:27:45 +02:00
$query -> bindValue ( ':id' , $postID , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
// leave a reply, linking to the new thread
2015-03-10 12:48:59 +01:00
$spost = array (
2012-05-19 10:27:45 +02:00
'mod' => true ,
'subject' => '' ,
'email' => '' ,
2013-03-20 12:46:48 +01:00
'name' => ( ! $config [ 'mod' ][ 'shadow_name' ] ? $config [ 'anonymous' ] : $config [ 'mod' ][ 'shadow_name' ]),
2012-05-19 10:27:45 +02:00
'capcode' => $config [ 'mod' ][ 'shadow_capcode' ],
'trip' => '' ,
'password' => '' ,
'has_file' => false ,
// attach to original thread
'thread' => $postID ,
'op' => false
);
2012-11-19 00:28:23 +01:00
2015-03-10 12:48:59 +01:00
$spost [ 'body' ] = $spost [ 'body_nomarkup' ] = sprintf ( $config [ 'mod' ][ 'shadow_mesage' ], '>>>/' . $targetBoard . '/' . $newID );
2024-02-23 22:49:23 +01:00
2015-03-10 12:48:59 +01:00
markup ( $spost [ 'body' ]);
2024-02-23 22:49:23 +01:00
2015-03-10 12:48:59 +01:00
$botID = post ( $spost );
2012-05-19 10:27:45 +02:00
buildThread ( $postID );
2024-02-23 22:49:23 +01:00
2012-05-22 07:25:22 +02:00
buildIndex ();
2024-02-23 22:49:23 +01:00
2015-03-10 13:48:33 +01:00
header ( 'Location: ?/' . sprintf ( $config [ 'board_path' ], $newboard [ 'uri' ]) . $config [ 'dir' ][ 'res' ] . link_for ( $op , false , $newboard ) .
2012-05-19 10:27:45 +02:00
'#' . $botID , true , $config [ 'redirect_http' ]);
} else {
deletePost ( $postID );
buildIndex ();
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
openBoard ( $targetBoard );
2015-03-10 13:48:33 +01:00
header ( 'Location: ?/' . sprintf ( $config [ 'board_path' ], $newboard [ 'uri' ]) . $config [ 'dir' ][ 'res' ] . link_for ( $op , false , $newboard ), true , $config [ 'redirect_http' ]);
2012-05-19 10:27:45 +02:00
}
}
2024-02-23 22:49:23 +01:00
2012-05-19 10:27:45 +02:00
$boards = listBoards ();
if ( count ( $boards ) <= 1 )
error ( _ ( 'Impossible to move thread; there is only one board.' ));
2024-02-23 22:49:23 +01:00
2012-08-27 07:19:05 +02:00
$security_token = make_secure_link_token ( $originBoard . '/move/' . $postID );
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Move thread' ), $config [ 'file_mod_move' ], array ( 'post' => $postID , 'board' => $originBoard , 'boards' => $boards , 'token' => $security_token ));
2012-05-19 10:27:45 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_ban_post ( Context $ctx , $board , $delete , $post , $token = false ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-20 11:47:55 +02:00
if ( ! openBoard ( $board ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2024-09-21 23:39:13 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'ban' ], $board ))
2012-04-20 11:47:55 +02:00
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2012-09-27 19:54:32 +02:00
$security_token = make_secure_link_token ( $board . '/ban/' . $post );
2024-02-23 22:49:23 +01:00
2013-09-18 00:47:34 +02:00
$query = prepare ( sprintf ( 'SELECT ' . ( $config [ 'ban_show_post' ] ? '*' : '`ip`, `thread`' ) .
' FROM ``posts_%s`` WHERE `id` = :id' , $board ));
2012-04-20 11:47:55 +02:00
$query -> bindValue ( ':id' , $post );
$query -> execute () or error ( db_error ( $query ));
2012-05-05 17:33:10 +02:00
if ( ! $_post = $query -> fetch ( PDO :: FETCH_ASSOC ))
2012-04-20 11:47:55 +02:00
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2012-04-20 13:37:48 +02:00
$thread = $_post [ 'thread' ];
$ip = $_post [ 'ip' ];
2012-08-27 07:19:05 +02:00
2012-04-20 13:37:48 +02:00
if ( isset ( $_POST [ 'new_ban' ], $_POST [ 'reason' ], $_POST [ 'length' ], $_POST [ 'board' ])) {
if ( isset ( $_POST [ 'ip' ]))
$ip = $_POST [ 'ip' ];
2024-02-23 22:49:23 +01:00
2022-08-20 02:02:09 +02:00
Bans :: new_ban ( $ip , $_POST [ 'reason' ], $_POST [ 'length' ], $_POST [ 'board' ] == '*' ? false : $_POST [ 'board' ],
2013-09-18 00:47:34 +02:00
false , $config [ 'ban_show_post' ] ? $_post : false );
2024-02-23 22:49:23 +01:00
2012-04-20 13:37:48 +02:00
if ( isset ( $_POST [ 'public_message' ], $_POST [ 'message' ])) {
// public ban message
2024-04-30 12:32:40 +02:00
$length_english = Bans :: parse_time ( $_POST [ 'length' ]) ? 'for ' . Format\until ( Bans :: parse_time ( $_POST [ 'length' ])) : 'permanently' ;
2013-08-01 00:59:54 +02:00
$_POST [ 'message' ] = preg_replace ( '/[\r\n]/' , '' , $_POST [ 'message' ]);
2013-07-24 17:30:01 +02:00
$_POST [ 'message' ] = str_replace ( '%length%' , $length_english , $_POST [ 'message' ]);
$_POST [ 'message' ] = str_replace ( '%LENGTH%' , strtoupper ( $length_english ), $_POST [ 'message' ]);
2013-08-01 04:14:26 +02:00
$query = prepare ( sprintf ( 'UPDATE ``posts_%s`` SET `body_nomarkup` = CONCAT(`body_nomarkup`, :body_nomarkup) WHERE `id` = :id' , $board ));
2012-04-20 13:37:48 +02:00
$query -> bindValue ( ':id' , $post );
2013-08-01 03:24:17 +02:00
$query -> bindValue ( ':body_nomarkup' , sprintf ( " \n <tinyboard ban message>%s</tinyboard> " , utf8tohtml ( $_POST [ 'message' ])));
2012-04-20 13:37:48 +02:00
$query -> execute () or error ( db_error ( $query ));
2013-08-01 00:59:54 +02:00
rebuildPost ( $post );
2024-02-23 22:49:23 +01:00
2012-04-20 13:37:48 +02:00
modLog ( " Attached a public ban message to post # { $post } : " . utf8tohtml ( $_POST [ 'message' ]));
buildThread ( $thread ? $thread : $post );
buildIndex ();
2012-05-07 16:49:48 +02:00
} elseif ( isset ( $_POST [ 'delete' ]) && ( int ) $_POST [ 'delete' ]) {
2012-04-20 13:37:48 +02:00
// Delete post
deletePost ( $post );
modLog ( " Deleted post # { $post } " );
// Rebuild board
buildIndex ();
2013-08-26 05:50:29 +02:00
// Rebuild themes
2024-08-16 18:32:32 +02:00
Vichan\Functions\Theme\rebuild_themes ( 'post-delete' , $board );
2012-04-20 13:37:48 +02:00
}
2024-02-23 22:49:23 +01:00
2012-04-20 13:37:48 +02:00
header ( 'Location: ?/' . sprintf ( $config [ 'board_path' ], $board ) . $config [ 'file_index' ], true , $config [ 'redirect_http' ]);
}
2024-02-23 22:49:23 +01:00
2012-04-20 13:37:48 +02:00
$args = array (
'ip' => $ip ,
'hide_ip' => ! hasPermission ( $config [ 'mod' ][ 'show_ip' ], $board ),
'post' => $post ,
'board' => $board ,
'delete' => ( bool ) $delete ,
2012-08-27 07:19:05 +02:00
'boards' => listBoards (),
2022-05-22 23:42:57 +02:00
'reasons' => $config [ 'premade_ban_reasons' ],
2012-08-27 07:19:05 +02:00
'token' => $security_token
2012-04-20 13:37:48 +02:00
);
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'New ban' ), $config [ 'file_mod_ban_form' ], $args );
2012-04-20 11:47:55 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_edit_post ( Context $ctx , $board , $edit_raw_html , $postID ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2013-01-08 04:31:09 +01:00
if ( ! openBoard ( $board ))
error ( $config [ 'error' ][ 'noboard' ]);
if ( ! hasPermission ( $config [ 'mod' ][ 'editpost' ], $board ))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-01-24 09:16:25 +01:00
if ( $edit_raw_html && ! hasPermission ( $config [ 'mod' ][ 'rawhtml' ], $board ))
error ( $config [ 'error' ][ 'noaccess' ]);
2013-01-08 04:31:09 +01:00
2013-01-24 09:16:25 +01:00
$security_token = make_secure_link_token ( $board . '/edit' . ( $edit_raw_html ? '_raw' : '' ) . '/' . $postID );
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( sprintf ( 'SELECT * FROM ``posts_%s`` WHERE `id` = :id' , $board ));
2013-01-23 18:16:09 +01:00
$query -> bindValue ( ':id' , $postID );
2013-01-08 07:52:13 +01:00
$query -> execute () or error ( db_error ( $query ));
2013-01-23 18:16:09 +01:00
if ( ! $post = $query -> fetch ( PDO :: FETCH_ASSOC ))
2013-01-08 07:52:13 +01:00
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2013-01-23 18:16:09 +01:00
if ( isset ( $_POST [ 'name' ], $_POST [ 'email' ], $_POST [ 'subject' ], $_POST [ 'body' ])) {
2014-12-24 15:08:19 +01:00
// Remove any modifiers they may have put in
$_POST [ 'body' ] = remove_modifiers ( $_POST [ 'body' ]);
// Add back modifiers in the original post
$modifiers = extract_modifiers ( $post [ 'body_nomarkup' ]);
foreach ( $modifiers as $key => $value ) {
$_POST [ 'body' ] .= " <tinyboard $key > $value </tinyboard> " ;
}
2013-01-24 09:16:25 +01:00
if ( $edit_raw_html )
2013-08-01 04:14:26 +02:00
$query = prepare ( sprintf ( 'UPDATE ``posts_%s`` SET `name` = :name, `email` = :email, `subject` = :subject, `body` = :body, `body_nomarkup` = :body_nomarkup WHERE `id` = :id' , $board ));
2013-01-24 09:16:25 +01:00
else
2013-08-01 04:14:26 +02:00
$query = prepare ( sprintf ( 'UPDATE ``posts_%s`` SET `name` = :name, `email` = :email, `subject` = :subject, `body_nomarkup` = :body WHERE `id` = :id' , $board ));
2013-01-23 18:16:09 +01:00
$query -> bindValue ( ':id' , $postID );
2017-07-30 01:23:18 +02:00
$query -> bindValue ( ':name' , $_POST [ 'name' ]);
2013-01-08 07:52:13 +01:00
$query -> bindValue ( ':email' , $_POST [ 'email' ]);
$query -> bindValue ( ':subject' , $_POST [ 'subject' ]);
$query -> bindValue ( ':body' , $_POST [ 'body' ]);
2013-08-01 01:50:25 +02:00
if ( $edit_raw_html ) {
2013-08-16 19:39:58 +02:00
$body_nomarkup = $_POST [ 'body' ] . " \n <tinyboard raw html>1</tinyboard> " ;
2013-08-01 01:50:25 +02:00
$query -> bindValue ( ':body_nomarkup' , $body_nomarkup );
}
2013-01-08 07:52:13 +01:00
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2013-01-27 09:02:47 +01:00
if ( $edit_raw_html ) {
modLog ( " Edited raw HTML of post # { $postID } " );
} else {
modLog ( " Edited post # { $postID } " );
2013-01-24 09:16:25 +01:00
rebuildPost ( $postID );
2013-01-27 09:02:47 +01:00
}
2024-02-23 22:49:23 +01:00
2013-01-23 18:16:09 +01:00
buildIndex ();
2013-08-26 06:36:41 +02:00
2024-08-16 18:32:32 +02:00
Vichan\Functions\Theme\rebuild_themes ( 'post' , $board );
2024-02-23 22:49:23 +01:00
2015-03-10 12:48:59 +01:00
header ( 'Location: ?/' . sprintf ( $config [ 'board_path' ], $board ) . $config [ 'dir' ][ 'res' ] . link_for ( $post ) . '#' . $postID , true , $config [ 'redirect_http' ]);
2013-01-08 07:52:13 +01:00
} else {
2014-12-24 15:08:19 +01:00
// Remove modifiers
$post [ 'body_nomarkup' ] = remove_modifiers ( $post [ 'body_nomarkup' ]);
2024-02-23 22:49:23 +01:00
2014-12-24 15:08:19 +01:00
$post [ 'body_nomarkup' ] = utf8tohtml ( $post [ 'body_nomarkup' ]);
$post [ 'body' ] = utf8tohtml ( $post [ 'body' ]);
2013-01-24 09:16:25 +01:00
if ( $config [ 'minify_html' ]) {
2014-12-24 15:08:19 +01:00
$post [ 'body_nomarkup' ] = str_replace ( " \n " , '
' , $post [ 'body_nomarkup' ]);
$post [ 'body' ] = str_replace ( " \n " , '
' , $post [ 'body' ]);
2013-08-01 23:18:10 +02:00
$post [ 'body_nomarkup' ] = str_replace ( " \r " , '' , $post [ 'body_nomarkup' ]);
$post [ 'body' ] = str_replace ( " \r " , '' , $post [ 'body' ]);
2013-08-31 05:23:29 +02:00
$post [ 'body_nomarkup' ] = str_replace ( " \t " , '	' , $post [ 'body_nomarkup' ]);
$post [ 'body' ] = str_replace ( " \t " , '	' , $post [ 'body' ]);
2013-01-24 09:16:25 +01:00
}
2014-12-24 15:08:19 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Edit post' ), $config [ 'file_mod_edit_post_form' ], array ( 'token' => $security_token , 'board' => $board , 'raw' => $edit_raw_html , 'post' => $post ));
2013-01-08 07:52:13 +01:00
}
2013-01-08 04:31:09 +01:00
}
2024-08-15 17:05:43 +02:00
function mod_delete ( Context $ctx , $board , $post ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-13 02:41:30 +02:00
if ( ! openBoard ( $board ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2012-04-13 02:41:30 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'delete' ], $board ))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-05 12:17:01 +02:00
// Delete post
2012-04-13 02:41:30 +02:00
deletePost ( $post );
// Record the action
modLog ( " Deleted post # { $post } " );
// Rebuild board
buildIndex ();
2013-08-26 05:50:29 +02:00
// Rebuild themes
2024-08-16 18:32:32 +02:00
Vichan\Functions\Theme\rebuild_themes ( 'post-delete' , $board );
2012-04-13 02:41:30 +02:00
// Redirect
header ( 'Location: ?/' . sprintf ( $config [ 'board_path' ], $board ) . $config [ 'file_index' ], true , $config [ 'redirect_http' ]);
}
2024-08-15 17:05:43 +02:00
function mod_deletefile ( Context $ctx , $board , $post , $file ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-21 07:29:57 +02:00
if ( ! openBoard ( $board ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2012-04-21 07:29:57 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'deletefile' ], $board ))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2012-04-21 07:29:57 +02:00
// Delete file
2014-04-30 23:18:35 +02:00
deleteFile ( $post , TRUE , $file );
2012-04-21 07:29:57 +02:00
// Record the action
modLog ( " Deleted file from post # { $post } " );
2024-02-23 22:49:23 +01:00
2012-04-21 07:29:57 +02:00
// Rebuild board
buildIndex ();
2013-08-26 05:50:29 +02:00
// Rebuild themes
2024-08-16 18:32:32 +02:00
Vichan\Functions\Theme\rebuild_themes ( 'post-delete' , $board );
2024-02-23 22:49:23 +01:00
2012-04-21 07:29:57 +02:00
// Redirect
header ( 'Location: ?/' . sprintf ( $config [ 'board_path' ], $board ) . $config [ 'file_index' ], true , $config [ 'redirect_http' ]);
}
2024-08-15 17:05:43 +02:00
function mod_spoiler_image ( Context $ctx , $board , $post , $file ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2013-08-08 21:41:21 +02:00
if ( ! openBoard ( $board ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2013-08-08 21:41:21 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'spoilerimage' ], $board ))
error ( $config [ 'error' ][ 'noaccess' ]);
2014-04-30 23:18:35 +02:00
// Delete file thumbnail
$query = prepare ( sprintf ( " SELECT `files`, `thread` FROM ``posts_%s`` WHERE id = :id " , $board ));
2013-08-11 15:54:11 +02:00
$query -> bindValue ( ':id' , $post , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
$result = $query -> fetch ( PDO :: FETCH_ASSOC );
2014-04-30 23:18:35 +02:00
$files = json_decode ( $result [ 'files' ]);
2013-08-11 15:54:11 +02:00
2014-09-27 18:21:54 +02:00
$size_spoiler_image = @ getimagesize ( $config [ 'spoiler_image' ]);
2014-04-30 23:18:35 +02:00
file_unlink ( $board . '/' . $config [ 'dir' ][ 'thumb' ] . $files [ $file ] -> thumb );
$files [ $file ] -> thumb = 'spoiler' ;
2014-10-07 03:02:50 +02:00
$files [ $file ] -> thumbwidth = $size_spoiler_image [ 0 ];
2014-09-27 18:21:54 +02:00
$files [ $file ] -> thumbheight = $size_spoiler_image [ 1 ];
2024-02-23 22:49:23 +01:00
2013-08-11 15:54:11 +02:00
// Make thumbnail spoiler
2014-04-30 23:18:35 +02:00
$query = prepare ( sprintf ( " UPDATE ``posts_%s`` SET `files` = :files WHERE `id` = :id " , $board ));
$query -> bindValue ( ':files' , json_encode ( $files ));
2013-08-08 21:41:21 +02:00
$query -> bindValue ( ':id' , $post , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
// Record the action
modLog ( " Spoilered file from post # { $post } " );
2013-08-11 15:54:11 +02:00
// Rebuild thread
buildThread ( $result [ 'thread' ] ? $result [ 'thread' ] : $post );
2013-08-08 21:41:21 +02:00
// Rebuild board
buildIndex ();
2013-08-26 05:50:29 +02:00
// Rebuild themes
2024-08-16 18:32:32 +02:00
Vichan\Functions\Theme\rebuild_themes ( 'post-delete' , $board );
2024-02-23 22:49:23 +01:00
2013-08-08 21:41:21 +02:00
// Redirect
header ( 'Location: ?/' . sprintf ( $config [ 'board_path' ], $board ) . $config [ 'file_index' ], true , $config [ 'redirect_http' ]);
}
2024-08-15 17:05:43 +02:00
function mod_deletebyip ( Context $ctx , $boardName , $post , $global = false ) {
2024-08-15 17:12:14 +02:00
global $board ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-21 07:42:33 +02:00
$global = ( bool ) $global ;
2024-02-23 22:49:23 +01:00
2012-04-21 07:42:33 +02:00
if ( ! openBoard ( $boardName ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2012-04-21 07:42:33 +02:00
if ( ! $global && ! hasPermission ( $config [ 'mod' ][ 'deletebyip' ], $boardName ))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2012-04-21 07:42:33 +02:00
if ( $global && ! hasPermission ( $config [ 'mod' ][ 'deletebyip_global' ], $boardName ))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2012-04-21 07:42:33 +02:00
// Find IP address
2013-08-01 04:14:26 +02:00
$query = prepare ( sprintf ( 'SELECT `ip` FROM ``posts_%s`` WHERE `id` = :id' , $boardName ));
2012-04-21 07:42:33 +02:00
$query -> bindValue ( ':id' , $post );
$query -> execute () or error ( db_error ( $query ));
2013-08-01 02:51:43 +02:00
if ( ! $ip = $query -> fetchColumn ())
2012-04-21 07:42:33 +02:00
error ( $config [ 'error' ][ 'invalidpost' ]);
2024-02-23 22:49:23 +01:00
2012-04-21 07:42:33 +02:00
$boards = $global ? listBoards () : array ( array ( 'uri' => $boardName ));
2024-02-23 22:49:23 +01:00
2012-04-21 07:42:33 +02:00
$query = '' ;
foreach ( $boards as $_board ) {
2013-08-01 04:14:26 +02:00
$query .= sprintf ( " SELECT `thread`, `id`, '%s' AS `board` FROM ``posts_%s`` WHERE `ip` = :ip UNION ALL " , $_board [ 'uri' ], $_board [ 'uri' ]);
2012-04-21 07:42:33 +02:00
}
$query = preg_replace ( '/UNION ALL $/' , '' , $query );
2024-02-23 22:49:23 +01:00
2012-04-21 07:42:33 +02:00
$query = prepare ( $query );
$query -> bindValue ( ':ip' , $ip );
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-04-21 07:42:33 +02:00
if ( $query -> rowCount () < 1 )
error ( $config [ 'error' ][ 'invalidpost' ]);
2024-02-23 22:49:23 +01:00
2013-09-01 17:20:57 +02:00
@ set_time_limit ( $config [ 'mod' ][ 'rebuild_timelimit' ]);
2024-02-23 22:49:23 +01:00
2024-08-15 17:21:41 +02:00
$threads_to_rebuild = [];
$threads_deleted = [];
2013-08-01 02:51:43 +02:00
while ( $post = $query -> fetch ( PDO :: FETCH_ASSOC )) {
2012-04-21 07:42:33 +02:00
openBoard ( $post [ 'board' ]);
2024-02-23 22:49:23 +01:00
2012-09-04 08:21:04 +02:00
deletePost ( $post [ 'id' ], false , false );
2024-08-16 18:32:32 +02:00
Vichan\Functions\Theme\rebuild_themes ( 'post-delete' , $board [ 'uri' ]);
2024-02-23 22:49:23 +01:00
2016-09-23 08:03:11 +02:00
buildIndex ();
2013-08-26 05:50:29 +02:00
2012-09-04 08:21:04 +02:00
if ( $post [ 'thread' ])
$threads_to_rebuild [ $post [ 'board' ]][ $post [ 'thread' ]] = true ;
else
$threads_deleted [ $post [ 'board' ]][ $post [ 'id' ]] = true ;
2012-04-21 07:42:33 +02:00
}
2024-02-23 22:49:23 +01:00
2012-09-04 08:21:04 +02:00
foreach ( $threads_to_rebuild as $_board => $_threads ) {
2012-04-21 07:42:33 +02:00
openBoard ( $_board );
2012-09-04 08:21:04 +02:00
foreach ( $_threads as $_thread => $_dummy ) {
if ( $_dummy && ! isset ( $threads_deleted [ $_board ][ $_thread ]))
buildThread ( $_thread );
}
2012-04-21 07:42:33 +02:00
buildIndex ();
}
2024-02-23 22:49:23 +01:00
2012-04-21 07:42:33 +02:00
if ( $global ) {
$board = false ;
}
2024-02-23 22:49:23 +01:00
2012-04-21 07:42:33 +02:00
// Record the action
2021-02-13 14:11:41 +01:00
$cip = cloak_ip ( $ip );
modLog ( " Deleted all posts by IP address: <a href= \" ?/IP/ $cip\ " > $cip </ a > " );
2024-02-23 22:49:23 +01:00
2012-04-21 07:42:33 +02:00
// Redirect
header ( 'Location: ?/' . sprintf ( $config [ 'board_path' ], $boardName ) . $config [ 'file_index' ], true , $config [ 'redirect_http' ]);
}
2024-08-15 17:05:43 +02:00
function mod_user ( Context $ctx , $uid ) {
2024-08-15 17:12:14 +02:00
global $mod ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-16 15:18:07 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'editusers' ]) && ! ( hasPermission ( $config [ 'mod' ][ 'change_password' ]) && $uid == $mod [ 'id' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( 'SELECT * FROM ``mods`` WHERE `id` = :id' );
2012-04-16 15:18:07 +02:00
$query -> bindValue ( ':id' , $uid );
$query -> execute () or error ( db_error ( $query ));
if ( ! $user = $query -> fetch ( PDO :: FETCH_ASSOC ))
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2012-04-16 15:18:07 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'editusers' ]) && isset ( $_POST [ 'username' ], $_POST [ 'password' ])) {
if ( isset ( $_POST [ 'allboards' ])) {
$boards = array ( '*' );
} else {
$_boards = listBoards ();
foreach ( $_boards as & $board ) {
$board = $board [ 'uri' ];
}
2024-02-23 22:49:23 +01:00
2024-08-15 17:21:41 +02:00
$boards = [];
2012-04-16 15:18:07 +02:00
foreach ( $_POST as $name => $value ) {
2013-07-31 08:08:55 +02:00
if ( preg_match ( '/^board_(' . $config [ 'board_regex' ] . ')$/u' , $name , $matches ) && in_array ( $matches [ 1 ], $_boards ))
2012-04-16 15:18:07 +02:00
$boards [] = $matches [ 1 ];
}
}
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( isset ( $_POST [ 'delete' ])) {
if ( ! hasPermission ( $config [ 'mod' ][ 'deleteusers' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( 'DELETE FROM ``mods`` WHERE `id` = :id' );
2012-05-05 17:33:10 +02:00
$query -> bindValue ( ':id' , $uid );
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
modLog ( 'Deleted user ' . utf8tohtml ( $user [ 'username' ]) . ' <small>(#' . $user [ 'id' ] . ')</small>' );
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
header ( 'Location: ?/users' , true , $config [ 'redirect_http' ]);
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
return ;
}
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( $_POST [ 'username' ] == '' )
error ( sprintf ( $config [ 'error' ][ 'required' ], 'username' ));
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( 'UPDATE ``mods`` SET `username` = :username, `boards` = :boards WHERE `id` = :id' );
2012-04-16 15:18:07 +02:00
$query -> bindValue ( ':id' , $uid );
$query -> bindValue ( ':username' , $_POST [ 'username' ]);
$query -> bindValue ( ':boards' , implode ( ',' , $boards ));
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( $user [ 'username' ] !== $_POST [ 'username' ]) {
// account was renamed
modLog ( 'Renamed user "' . utf8tohtml ( $user [ 'username' ]) . '" <small>(#' . $user [ 'id' ] . ')</small> to "' . utf8tohtml ( $_POST [ 'username' ]) . '"' );
}
2024-02-23 22:49:23 +01:00
2012-04-16 15:18:07 +02:00
if ( $_POST [ 'password' ] != '' ) {
2016-05-05 06:43:22 +02:00
list ( $version , $password ) = crypt_password ( $_POST [ 'password' ]);
2016-04-22 05:35:43 +02:00
2016-05-05 06:43:22 +02:00
$query = prepare ( 'UPDATE ``mods`` SET `password` = :password, `version` = :version WHERE `id` = :id' );
2012-04-16 15:18:07 +02:00
$query -> bindValue ( ':id' , $uid );
2013-07-24 17:15:55 +02:00
$query -> bindValue ( ':password' , $password );
2016-05-05 06:43:22 +02:00
$query -> bindValue ( ':version' , $version );
2012-04-16 15:18:07 +02:00
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
modLog ( 'Changed password for ' . utf8tohtml ( $_POST [ 'username' ]) . ' <small>(#' . $user [ 'id' ] . ')</small>' );
2024-02-23 22:49:23 +01:00
2012-04-16 15:18:07 +02:00
if ( $uid == $mod [ 'id' ]) {
login ( $_POST [ 'username' ], $_POST [ 'password' ]);
setCookies ();
}
}
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'manageusers' ]))
header ( 'Location: ?/users' , true , $config [ 'redirect_http' ]);
else
header ( 'Location: ?/' , true , $config [ 'redirect_http' ]);
2024-02-23 22:49:23 +01:00
2012-04-16 15:18:07 +02:00
return ;
}
2024-02-23 22:49:23 +01:00
2012-04-21 04:42:41 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'change_password' ]) && $uid == $mod [ 'id' ] && isset ( $_POST [ 'password' ])) {
2012-04-16 15:18:07 +02:00
if ( $_POST [ 'password' ] != '' ) {
2016-05-05 06:43:22 +02:00
list ( $version , $password ) = crypt_password ( $_POST [ 'password' ]);
2013-07-24 17:15:55 +02:00
2016-05-05 06:43:22 +02:00
$query = prepare ( 'UPDATE ``mods`` SET `password` = :password, `version` = :version WHERE `id` = :id' );
2012-04-16 15:18:07 +02:00
$query -> bindValue ( ':id' , $uid );
2013-07-24 17:15:55 +02:00
$query -> bindValue ( ':password' , $password );
2016-05-05 06:43:22 +02:00
$query -> bindValue ( ':version' , $version );
2012-04-16 15:18:07 +02:00
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
modLog ( 'Changed own password' );
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
login ( $user [ 'username' ], $_POST [ 'password' ]);
2012-04-16 15:18:07 +02:00
setCookies ();
}
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'manageusers' ]))
header ( 'Location: ?/users' , true , $config [ 'redirect_http' ]);
else
header ( 'Location: ?/' , true , $config [ 'redirect_http' ]);
2024-02-23 22:49:23 +01:00
2012-04-16 15:18:07 +02:00
return ;
}
2024-02-23 22:49:23 +01:00
2012-04-16 15:18:07 +02:00
if ( hasPermission ( $config [ 'mod' ][ 'modlog' ])) {
2013-08-01 04:14:26 +02:00
$query = prepare ( 'SELECT * FROM ``modlogs`` WHERE `mod` = :id ORDER BY `time` DESC LIMIT 5' );
2012-04-16 15:18:07 +02:00
$query -> bindValue ( ':id' , $uid );
$query -> execute () or error ( db_error ( $query ));
$log = $query -> fetchAll ( PDO :: FETCH_ASSOC );
} else {
2024-08-15 17:21:41 +02:00
$log = [];
2012-04-16 15:18:07 +02:00
}
2024-02-23 22:49:23 +01:00
2012-04-16 15:18:07 +02:00
$user [ 'boards' ] = explode ( ',' , $user [ 'boards' ]);
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Edit user' ), $config [ 'file_mod_user' ], array (
2013-09-23 08:48:56 +02:00
'user' => $user ,
'logs' => $log ,
'boards' => listBoards (),
'token' => make_secure_link_token ( 'users/' . $user [ 'id' ])
));
2012-04-16 15:18:07 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_user_new ( Context $ctx ) {
2012-05-18 12:30:55 +02:00
global $pdo , $config ;
2024-02-23 22:49:23 +01:00
2012-05-07 06:08:40 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'createusers' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( isset ( $_POST [ 'username' ], $_POST [ 'password' ], $_POST [ 'type' ])) {
if ( $_POST [ 'username' ] == '' )
error ( sprintf ( $config [ 'error' ][ 'required' ], 'username' ));
if ( $_POST [ 'password' ] == '' )
error ( sprintf ( $config [ 'error' ][ 'required' ], 'password' ));
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( isset ( $_POST [ 'allboards' ])) {
$boards = array ( '*' );
} else {
$_boards = listBoards ();
foreach ( $_boards as & $board ) {
$board = $board [ 'uri' ];
}
2024-02-23 22:49:23 +01:00
2024-08-15 17:21:41 +02:00
$boards = [];
2012-05-05 17:33:10 +02:00
foreach ( $_POST as $name => $value ) {
2013-07-31 08:08:55 +02:00
if ( preg_match ( '/^board_(' . $config [ 'board_regex' ] . ')$/u' , $name , $matches ) && in_array ( $matches [ 1 ], $_boards ))
2012-05-05 17:33:10 +02:00
$boards [] = $matches [ 1 ];
}
}
2024-02-23 22:49:23 +01:00
2013-09-08 17:38:32 +02:00
$type = ( int ) $_POST [ 'type' ];
if ( ! isset ( $config [ 'mod' ][ 'groups' ][ $type ]) || $type == DISABLED )
2012-05-05 17:33:10 +02:00
error ( sprintf ( $config [ 'error' ][ 'invalidfield' ], 'type' ));
2024-02-23 22:49:23 +01:00
2016-05-05 06:43:22 +02:00
list ( $version , $password ) = crypt_password ( $_POST [ 'password' ]);
2024-02-23 22:49:23 +01:00
2016-05-05 06:43:22 +02:00
$query = prepare ( 'INSERT INTO ``mods`` VALUES (NULL, :username, :password, :version, :type, :boards)' );
2012-05-05 17:33:10 +02:00
$query -> bindValue ( ':username' , $_POST [ 'username' ]);
2013-07-24 17:15:55 +02:00
$query -> bindValue ( ':password' , $password );
2016-05-05 06:43:22 +02:00
$query -> bindValue ( ':version' , $version );
2013-09-08 17:38:32 +02:00
$query -> bindValue ( ':type' , $type );
2012-05-05 17:33:10 +02:00
$query -> bindValue ( ':boards' , implode ( ',' , $boards ));
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-19 12:52:45 +02:00
$userID = $pdo -> lastInsertId ();
2024-02-23 22:49:23 +01:00
2012-05-07 06:08:40 +02:00
modLog ( 'Created a new user: ' . utf8tohtml ( $_POST [ 'username' ]) . ' <small>(#' . $userID . ')</small>' );
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
header ( 'Location: ?/users' , true , $config [ 'redirect_http' ]);
return ;
}
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'New user' ), $config [ 'file_mod_user' ], array ( 'new' => true , 'boards' => listBoards (), 'token' => make_secure_link_token ( 'users/new' )));
2012-05-05 17:33:10 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_users ( Context $ctx ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-13 14:00:40 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'manageusers' ]))
2012-04-13 13:43:01 +02:00
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-09-23 08:48:56 +02:00
$query = query ( " SELECT
* ,
( SELECT `time` FROM `` modlogs `` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1 ) AS `last` ,
( SELECT `text` FROM `` modlogs `` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1 ) AS `action`
FROM `` mods `` ORDER BY `type` DESC , `id` " ) or error(db_error());
2012-05-28 09:08:29 +02:00
$users = $query -> fetchAll ( PDO :: FETCH_ASSOC );
2024-02-23 22:49:23 +01:00
2013-09-23 08:48:56 +02:00
foreach ( $users as & $user ) {
$user [ 'promote_token' ] = make_secure_link_token ( " users/ { $user [ 'id' ] } /promote " );
$user [ 'demote_token' ] = make_secure_link_token ( " users/ { $user [ 'id' ] } /demote " );
}
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( sprintf ( '%s (%d)' , _ ( 'Manage users' ), count ( $users )), $config [ 'file_mod_users' ], array ( 'users' => $users ));
2012-04-13 14:00:40 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_user_promote ( Context $ctx , $uid , $action ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-14 14:28:21 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'promoteusers' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-09-08 17:33:51 +02:00
$query = prepare ( " SELECT `type`, `username` FROM ``mods`` WHERE `id` = :id " );
2012-04-14 14:28:21 +02:00
$query -> bindValue ( ':id' , $uid );
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2013-09-08 17:33:51 +02:00
if ( ! $mod = $query -> fetch ( PDO :: FETCH_ASSOC ))
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2013-09-08 17:33:51 +02:00
$new_group = false ;
2024-02-23 22:49:23 +01:00
2013-09-08 17:33:51 +02:00
$groups = $config [ 'mod' ][ 'groups' ];
if ( $action == 'demote' )
$groups = array_reverse ( $groups , true );
2024-02-23 22:49:23 +01:00
2013-09-08 17:33:51 +02:00
foreach ( $groups as $group_value => $group_name ) {
if ( $action == 'promote' && $group_value > $mod [ 'type' ]) {
$new_group = $group_value ;
break ;
} elseif ( $action == 'demote' && $group_value < $mod [ 'type' ]) {
$new_group = $group_value ;
break ;
}
}
2024-02-23 22:49:23 +01:00
2013-09-08 17:33:51 +02:00
if ( $new_group === false || $new_group == DISABLED )
error ( _ ( 'Impossible to promote/demote user.' ));
2024-02-23 22:49:23 +01:00
2013-09-08 17:33:51 +02:00
$query = prepare ( " UPDATE ``mods`` SET `type` = :group_value WHERE `id` = :id " );
$query -> bindValue ( ':id' , $uid );
$query -> bindValue ( ':group_value' , $new_group );
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2013-09-08 17:33:51 +02:00
modLog (( $action == 'promote' ? 'Promoted' : 'Demoted' ) . ' user "' .
utf8tohtml ( $mod [ 'username' ]) . '" to ' . $config [ 'mod' ][ 'groups' ][ $new_group ]);
2024-02-23 22:49:23 +01:00
2012-04-14 14:28:21 +02:00
header ( 'Location: ?/users' , true , $config [ 'redirect_http' ]);
}
2024-08-15 17:05:43 +02:00
function mod_pm ( Context $ctx , $id , $reply = false ) {
2012-04-16 08:40:24 +02:00
global $mod , $config ;
2024-02-23 22:49:23 +01:00
2012-05-07 06:08:40 +02:00
if ( $reply && ! hasPermission ( $config [ 'mod' ][ 'create_pm' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( " SELECT ``mods``.`username`, `mods_to`.`username` AS `to_username`, ``pms``.* FROM ``pms`` LEFT JOIN ``mods`` ON ``mods``.`id` = `sender` LEFT JOIN ``mods`` AS `mods_to` ON `mods_to`.`id` = `to` WHERE ``pms``.`id` = :id " );
2012-04-16 08:40:24 +02:00
$query -> bindValue ( ':id' , $id );
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-04-16 08:40:24 +02:00
if (( ! $pm = $query -> fetch ( PDO :: FETCH_ASSOC )) || ( $pm [ 'to' ] != $mod [ 'id' ] && ! hasPermission ( $config [ 'mod' ][ 'master_pm' ])))
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2012-04-16 08:40:24 +02:00
if ( isset ( $_POST [ 'delete' ])) {
2013-08-01 04:14:26 +02:00
$query = prepare ( " DELETE FROM ``pms`` WHERE `id` = :id " );
2012-04-16 08:40:24 +02:00
$query -> bindValue ( ':id' , $id );
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-20 11:06:27 +02:00
if ( $config [ 'cache' ][ 'enabled' ]) {
cache :: delete ( 'pm_unread_' . $mod [ 'id' ]);
cache :: delete ( 'pm_unreadcount_' . $mod [ 'id' ]);
}
2024-02-23 22:49:23 +01:00
2012-04-16 08:40:24 +02:00
header ( 'Location: ?/' , true , $config [ 'redirect_http' ]);
return ;
}
2024-02-23 22:49:23 +01:00
2012-04-16 08:40:24 +02:00
if ( $pm [ 'unread' ] && $pm [ 'to' ] == $mod [ 'id' ]) {
2013-08-01 04:14:26 +02:00
$query = prepare ( " UPDATE ``pms`` SET `unread` = 0 WHERE `id` = :id " );
2012-04-16 08:40:24 +02:00
$query -> bindValue ( ':id' , $id );
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-20 11:06:27 +02:00
if ( $config [ 'cache' ][ 'enabled' ]) {
cache :: delete ( 'pm_unread_' . $mod [ 'id' ]);
cache :: delete ( 'pm_unreadcount_' . $mod [ 'id' ]);
}
2024-02-23 22:49:23 +01:00
2012-04-16 08:40:24 +02:00
modLog ( 'Read a PM' );
}
2024-02-23 22:49:23 +01:00
2012-04-16 08:40:24 +02:00
if ( $reply ) {
if ( ! $pm [ 'to_username' ])
error ( $config [ 'error' ][ '404' ]); // deleted?
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( sprintf ( '%s %s' , _ ( 'New PM for' ), $pm [ 'to_username' ]), $config [ 'file_mod_new_pm' ], array (
2013-09-23 08:48:56 +02:00
'username' => $pm [ 'username' ],
'id' => $pm [ 'sender' ],
'message' => quote ( $pm [ 'message' ]),
'token' => make_secure_link_token ( 'new_PM/' . $pm [ 'username' ])
2012-05-05 17:33:10 +02:00
));
2012-04-16 08:40:24 +02:00
} else {
2022-08-29 16:50:45 +02:00
mod_page ( sprintf ( '%s – #%d' , _ ( 'Private message' ), $id ), $config [ 'file_mod_pm' ], $pm );
2012-04-16 08:40:24 +02:00
}
}
2024-08-15 17:05:43 +02:00
function mod_inbox ( Context $ctx ) {
2024-08-15 17:12:14 +02:00
global $mod ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( 'SELECT `unread`,``pms``.`id`, `time`, `sender`, `to`, `message`, `username` FROM ``pms`` LEFT JOIN ``mods`` ON ``mods``.`id` = `sender` WHERE `to` = :mod ORDER BY `unread` DESC, `time` DESC' );
2012-05-05 17:33:10 +02:00
$query -> bindValue ( ':mod' , $mod [ 'id' ]);
$query -> execute () or error ( db_error ( $query ));
$messages = $query -> fetchAll ( PDO :: FETCH_ASSOC );
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( 'SELECT COUNT(*) FROM ``pms`` WHERE `to` = :mod AND `unread` = 1' );
2012-05-05 17:33:10 +02:00
$query -> bindValue ( ':mod' , $mod [ 'id' ]);
$query -> execute () or error ( db_error ( $query ));
2013-08-01 02:51:43 +02:00
$unread = $query -> fetchColumn ();
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
foreach ( $messages as & $message ) {
$message [ 'snippet' ] = pm_snippet ( $message [ 'message' ]);
}
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( sprintf ( '%s (%s)' , _ ( 'PM inbox' ), count ( $messages ) > 0 ? $unread . ' unread' : 'empty' ), $config [ 'file_mod_inbox' ], array (
2012-05-05 17:33:10 +02:00
'messages' => $messages ,
'unread' => $unread
));
}
2024-08-15 17:05:43 +02:00
function mod_new_pm ( Context $ctx , $username ) {
2024-08-15 17:12:14 +02:00
global $mod ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-13 14:00:40 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'create_pm' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( " SELECT `id` FROM ``mods`` WHERE `username` = :username " );
2012-04-13 14:00:40 +02:00
$query -> bindValue ( ':username' , $username );
$query -> execute () or error ( db_error ( $query ));
2013-08-01 02:51:43 +02:00
if ( ! $id = $query -> fetchColumn ()) {
2012-04-14 14:28:21 +02:00
// Old style ?/PM: by user ID
2013-08-01 04:14:26 +02:00
$query = prepare ( " SELECT `username` FROM ``mods`` WHERE `id` = :username " );
2012-04-14 14:28:21 +02:00
$query -> bindValue ( ':username' , $username );
$query -> execute () or error ( db_error ( $query ));
2013-08-01 02:51:43 +02:00
if ( $username = $query -> fetchColumn ())
2012-04-14 14:28:21 +02:00
header ( 'Location: ?/new_PM/' . $username , true , $config [ 'redirect_http' ]);
else
error ( $config [ 'error' ][ '404' ]);
}
2024-02-23 22:49:23 +01:00
2012-04-13 14:00:40 +02:00
if ( isset ( $_POST [ 'message' ])) {
2013-08-01 00:59:54 +02:00
$_POST [ 'message' ] = escape_markup_modifiers ( $_POST [ 'message' ]);
2012-04-13 14:00:40 +02:00
markup ( $_POST [ 'message' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( " INSERT INTO ``pms`` VALUES (NULL, :me, :id, :message, :time, 1) " );
2012-04-13 14:00:40 +02:00
$query -> bindValue ( ':me' , $mod [ 'id' ]);
$query -> bindValue ( ':id' , $id );
$query -> bindValue ( ':message' , $_POST [ 'message' ]);
$query -> bindValue ( ':time' , time ());
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-05-20 11:06:27 +02:00
if ( $config [ 'cache' ][ 'enabled' ]) {
cache :: delete ( 'pm_unread_' . $id );
cache :: delete ( 'pm_unreadcount_' . $id );
}
2024-02-23 22:49:23 +01:00
2012-04-16 08:40:24 +02:00
modLog ( 'Sent a PM to ' . utf8tohtml ( $username ));
2024-02-23 22:49:23 +01:00
2012-04-13 14:00:40 +02:00
header ( 'Location: ?/' , true , $config [ 'redirect_http' ]);
}
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( sprintf ( '%s %s' , _ ( 'New PM for' ), $username ), $config [ 'file_mod_new_pm' ], array (
2013-09-23 08:48:56 +02:00
'username' => $username ,
'id' => $id ,
'token' => make_secure_link_token ( 'new_PM/' . $username )
));
2012-04-13 13:43:01 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_rebuild ( Context $ctx ) {
2024-08-15 17:12:14 +02:00
global $twig ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-14 14:28:21 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'rebuild' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2012-04-14 14:58:36 +02:00
if ( isset ( $_POST [ 'rebuild' ])) {
2013-09-01 17:20:57 +02:00
@ set_time_limit ( $config [ 'mod' ][ 'rebuild_timelimit' ]);
2024-02-23 22:49:23 +01:00
2024-08-15 17:21:41 +02:00
$log = [];
2012-04-14 14:58:36 +02:00
$boards = listBoards ();
2024-08-15 17:21:41 +02:00
$rebuilt_scripts = [];
2024-02-23 22:49:23 +01:00
2012-04-14 14:58:36 +02:00
if ( isset ( $_POST [ 'rebuild_cache' ])) {
2012-04-21 07:29:57 +02:00
if ( $config [ 'cache' ][ 'enabled' ]) {
$log [] = 'Flushing cache' ;
Cache :: flush ();
}
2024-02-23 22:49:23 +01:00
2012-04-14 14:58:36 +02:00
$log [] = 'Clearing template cache' ;
load_twig ();
2023-03-29 23:59:28 +02:00
$twig -> getCache () -> clear ();
2012-04-14 14:58:36 +02:00
}
2024-02-23 22:49:23 +01:00
2012-04-14 14:58:36 +02:00
if ( isset ( $_POST [ 'rebuild_themes' ])) {
$log [] = 'Regenerating theme files' ;
2024-08-16 18:32:32 +02:00
Vichan\Functions\Theme\rebuild_themes ( 'all' );
2012-04-14 14:58:36 +02:00
}
2024-02-23 22:49:23 +01:00
2012-04-14 14:58:36 +02:00
if ( isset ( $_POST [ 'rebuild_javascript' ])) {
$log [] = 'Rebuilding <strong>' . $config [ 'file_script' ] . '</strong>' ;
buildJavascript ();
$rebuilt_scripts [] = $config [ 'file_script' ];
}
2024-02-23 22:49:23 +01:00
2012-04-14 14:58:36 +02:00
foreach ( $boards as $board ) {
2012-04-15 12:04:26 +02:00
if ( ! ( isset ( $_POST [ 'boards_all' ]) || isset ( $_POST [ 'board_' . $board [ 'uri' ]])))
2012-04-14 14:58:36 +02:00
continue ;
2024-02-23 22:49:23 +01:00
2012-04-14 14:58:36 +02:00
openBoard ( $board [ 'uri' ]);
2013-09-14 20:22:27 +02:00
$config [ 'try_smarter' ] = false ;
2024-02-23 22:49:23 +01:00
2012-04-16 09:33:13 +02:00
if ( isset ( $_POST [ 'rebuild_index' ])) {
buildIndex ();
$log [] = '<strong>' . sprintf ( $config [ 'board_abbreviation' ], $board [ 'uri' ]) . '</strong>: Creating index pages' ;
}
2024-02-23 22:49:23 +01:00
2012-04-16 09:33:13 +02:00
if ( isset ( $_POST [ 'rebuild_javascript' ]) && ! in_array ( $config [ 'file_script' ], $rebuilt_scripts )) {
2012-04-14 14:58:36 +02:00
$log [] = '<strong>' . sprintf ( $config [ 'board_abbreviation' ], $board [ 'uri' ]) . '</strong>: Rebuilding <strong>' . $config [ 'file_script' ] . '</strong>' ;
buildJavascript ();
$rebuilt_scripts [] = $config [ 'file_script' ];
}
2024-02-23 22:49:23 +01:00
2012-04-16 09:33:13 +02:00
if ( isset ( $_POST [ 'rebuild_thread' ])) {
2013-08-01 04:14:26 +02:00
$query = query ( sprintf ( " SELECT `id` FROM ``posts_%s`` WHERE `thread` IS NULL " , $board [ 'uri' ])) or error ( db_error ());
2012-04-16 09:33:13 +02:00
while ( $post = $query -> fetch ( PDO :: FETCH_ASSOC )) {
$log [] = '<strong>' . sprintf ( $config [ 'board_abbreviation' ], $board [ 'uri' ]) . '</strong>: Rebuilding thread #' . $post [ 'id' ];
buildThread ( $post [ 'id' ]);
}
2012-04-14 14:58:36 +02:00
}
}
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Rebuild' ), $config [ 'file_mod_rebuilt' ], array ( 'logs' => $log ));
2012-04-14 14:58:36 +02:00
return ;
}
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Rebuild' ), $config [ 'file_mod_rebuild' ], array (
2013-09-23 08:48:56 +02:00
'boards' => listBoards (),
'token' => make_secure_link_token ( 'rebuild' )
));
2012-04-14 14:28:21 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_reports ( Context $ctx ) {
2024-08-15 17:12:14 +02:00
global $mod ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2012-04-16 09:28:57 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'reports' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( " SELECT * FROM ``reports`` ORDER BY `time` DESC LIMIT :limit " );
2012-04-16 09:28:57 +02:00
$query -> bindValue ( ':limit' , $config [ 'mod' ][ 'recent_reports' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
$reports = $query -> fetchAll ( PDO :: FETCH_ASSOC );
2024-02-23 22:49:23 +01:00
2024-08-15 17:21:41 +02:00
$report_queries = [];
2023-07-28 20:32:42 +02:00
foreach ( $reports as $report ) {
2012-04-16 09:28:57 +02:00
if ( ! isset ( $report_queries [ $report [ 'board' ]]))
2024-08-15 17:21:41 +02:00
$report_queries [ $report [ 'board' ]] = [];
2012-04-16 09:28:57 +02:00
$report_queries [ $report [ 'board' ]][] = $report [ 'post' ];
}
2024-02-23 22:49:23 +01:00
2024-08-15 17:21:41 +02:00
$report_posts = [];
2012-04-16 09:28:57 +02:00
foreach ( $report_queries as $board => $posts ) {
2024-08-15 17:21:41 +02:00
$report_posts [ $board ] = [];
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = query ( sprintf ( 'SELECT * FROM ``posts_%s`` WHERE `id` = ' . implode ( ' OR `id` = ' , $posts ), $board )) or error ( db_error ());
2013-08-01 02:51:43 +02:00
while ( $post = $query -> fetch ( PDO :: FETCH_ASSOC )) {
2012-04-16 09:28:57 +02:00
$report_posts [ $board ][ $post [ 'id' ]] = $post ;
}
}
2024-02-23 22:49:23 +01:00
2012-05-25 13:40:01 +02:00
$count = 0 ;
2012-04-16 09:28:57 +02:00
$body = '' ;
foreach ( $reports as $report ) {
if ( ! isset ( $report_posts [ $report [ 'board' ]][ $report [ 'post' ]])) {
// // Invalid report (post has since been deleted)
2013-08-01 04:14:26 +02:00
$query = prepare ( " DELETE FROM ``reports`` WHERE `post` = :id AND `board` = :board " );
2012-04-16 09:28:57 +02:00
$query -> bindValue ( ':id' , $report [ 'post' ], PDO :: PARAM_INT );
$query -> bindValue ( ':board' , $report [ 'board' ]);
$query -> execute () or error ( db_error ( $query ));
continue ;
}
2024-02-23 22:49:23 +01:00
2012-04-16 09:28:57 +02:00
openBoard ( $report [ 'board' ]);
2024-02-23 22:49:23 +01:00
2012-04-16 09:28:57 +02:00
$post = & $report_posts [ $report [ 'board' ]][ $report [ 'post' ]];
2024-02-23 22:49:23 +01:00
2012-04-16 09:28:57 +02:00
if ( ! $post [ 'thread' ]) {
// Still need to fix this:
2013-08-16 13:08:01 +02:00
$po = new Thread ( $post , '?/' , $mod , false );
2012-04-16 09:28:57 +02:00
} else {
2013-08-16 13:08:01 +02:00
$po = new Post ( $post , '?/' , $mod );
2012-04-16 09:28:57 +02:00
}
2024-02-23 22:49:23 +01:00
2012-04-16 09:28:57 +02:00
// a little messy and inefficient
2022-08-29 16:50:45 +02:00
$append_html = Element ( $config [ 'file_mod_report' ], array (
2013-09-23 08:48:56 +02:00
'report' => $report ,
'config' => $config ,
'mod' => $mod ,
'token' => make_secure_link_token ( 'reports/' . $report [ 'id' ] . '/dismiss' ),
2023-04-24 04:15:44 +02:00
'token_all' => make_secure_link_token ( 'reports/' . $report [ 'id' ] . '/dismiss&all' ),
'token_post' => make_secure_link_token ( 'reports/' . $report [ 'id' ] . '/dismiss&post' ),
2013-09-23 08:48:56 +02:00
));
2024-02-23 22:49:23 +01:00
2012-04-16 09:28:57 +02:00
// Bug fix for https://github.com/savetheinternet/Tinyboard/issues/21
$po -> body = truncate ( $po -> body , $po -> link (), $config [ 'body_truncate' ] - substr_count ( $append_html , '<br>' ));
2024-02-23 22:49:23 +01:00
2012-04-16 09:28:57 +02:00
if ( mb_strlen ( $po -> body ) + mb_strlen ( $append_html ) > $config [ 'body_truncate_char' ]) {
// still too long; temporarily increase limit in the config
$__old_body_truncate_char = $config [ 'body_truncate_char' ];
$config [ 'body_truncate_char' ] = mb_strlen ( $po -> body ) + mb_strlen ( $append_html );
}
2024-02-23 22:49:23 +01:00
2012-04-16 09:28:57 +02:00
$po -> body .= $append_html ;
2024-02-23 22:49:23 +01:00
2012-04-16 09:28:57 +02:00
$body .= $po -> build ( true ) . '<hr>' ;
2024-02-23 22:49:23 +01:00
2012-05-05 17:33:10 +02:00
if ( isset ( $__old_body_truncate_char ))
2012-04-16 09:28:57 +02:00
$config [ 'body_truncate_char' ] = $__old_body_truncate_char ;
2024-02-23 22:49:23 +01:00
2012-05-25 13:40:01 +02:00
$count ++ ;
2012-04-16 09:28:57 +02:00
}
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( sprintf ( '%s (%d)' , _ ( 'Report queue' ), $count ), $config [ 'file_mod_reports' ], array ( 'reports' => $body , 'count' => $count ));
2012-04-16 09:28:57 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_report_dismiss ( Context $ctx , $id , $action ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = prepare ( " SELECT `post`, `board`, `ip` FROM ``reports`` WHERE `id` = :id " );
2012-04-16 09:28:57 +02:00
$query -> bindValue ( ':id' , $id );
$query -> execute () or error ( db_error ( $query ));
if ( $report = $query -> fetch ( PDO :: FETCH_ASSOC )) {
$ip = $report [ 'ip' ];
$board = $report [ 'board' ];
$post = $report [ 'post' ];
} else
error ( $config [ 'error' ][ '404' ]);
2024-02-23 22:49:23 +01:00
2023-04-24 04:15:44 +02:00
switch ( $action ){
case '&post' :
if ( ! hasPermission ( $config [ 'mod' ][ 'report_dismiss_post' ], $board ))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2023-04-24 04:15:44 +02:00
$query = prepare ( " DELETE FROM ``reports`` WHERE `post` = :post " );
$query -> bindValue ( ':post' , $post );
modLog ( " Dismissed all reports for post # { $id } " , $board );
2023-06-22 13:49:22 +02:00
break ;
2023-04-24 04:15:44 +02:00
case '&all' :
if ( ! hasPermission ( $config [ 'mod' ][ 'report_dismiss_ip' ], $board ))
error ( $config [ 'error' ][ 'noaccess' ]);
$query = prepare ( " DELETE FROM ``reports`` WHERE `ip` = :ip " );
$query -> bindValue ( ':ip' , $ip );
$cip = cloak_ip ( $ip );
modLog ( " Dismissed all reports by <a href= \" ?/IP/ $cip\ " > $cip </ a > " );
break ;
case '' :
default :
if ( ! hasPermission ( $config [ 'mod' ][ 'report_dismiss' ], $board ))
error ( $config [ 'error' ][ 'noaccess' ]);
$query = prepare ( " DELETE FROM ``reports`` WHERE `id` = :id " );
$query -> bindValue ( ':id' , $id );
modLog ( " Dismissed a report for post # { $id } " , $board );
break ;
2012-04-16 09:28:57 +02:00
}
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-04-16 09:28:57 +02:00
header ( 'Location: ?/reports' , true , $config [ 'redirect_http' ]);
}
2024-08-15 17:05:43 +02:00
function mod_recent_posts ( Context $ctx , $lim ) {
2024-08-15 17:12:14 +02:00
global $mod , $pdo ;
$config = $ctx -> get ( 'config' );
2014-03-17 23:11:16 +01:00
if ( ! hasPermission ( $config [ 'mod' ][ 'recent' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
$limit = ( is_numeric ( $lim )) ? $lim : 25 ;
2014-07-19 20:41:48 +02:00
$last_time = ( isset ( $_GET [ 'last' ]) && is_numeric ( $_GET [ 'last' ])) ? $_GET [ 'last' ] : 0 ;
2014-03-17 23:11:16 +01:00
2024-08-15 17:21:41 +02:00
$mod_boards = [];
2014-03-17 23:11:16 +01:00
$boards = listBoards ();
//if not all boards
if ( $mod [ 'boards' ][ 0 ] != '*' ) {
foreach ( $boards as $board ) {
if ( in_array ( $board [ 'uri' ], $mod [ 'boards' ]))
$mod_boards [] = $board ;
}
} else {
$mod_boards = $boards ;
}
// Manually build an SQL query
$query = 'SELECT * FROM (' ;
foreach ( $mod_boards as $board ) {
$query .= sprintf ( 'SELECT *, %s AS `board` FROM ``posts_%s`` UNION ALL ' , $pdo -> quote ( $board [ 'uri' ]), $board [ 'uri' ]);
}
// Remove the last "UNION ALL" seperator and complete the query
2014-07-19 20:41:48 +02:00
$query = preg_replace ( '/UNION ALL $/' , ') AS `all_posts` WHERE (`time` < :last_time OR NOT :last_time) ORDER BY `time` DESC LIMIT ' . $limit , $query );
$query = prepare ( $query );
$query -> bindValue ( ':last_time' , $last_time );
$query -> execute () or error ( db_error ( $query ));
2014-03-17 23:11:16 +01:00
$posts = $query -> fetchAll ( PDO :: FETCH_ASSOC );
2014-07-19 20:41:48 +02:00
foreach ( $posts as & $post ) {
2014-03-17 23:11:16 +01:00
openBoard ( $post [ 'board' ]);
if ( ! $post [ 'thread' ]) {
// Still need to fix this:
$po = new Thread ( $post , '?/' , $mod , false );
2014-07-19 20:41:48 +02:00
$post [ 'built' ] = $po -> build ( true );
2014-03-17 23:11:16 +01:00
} else {
$po = new Post ( $post , '?/' , $mod );
2014-07-19 20:41:48 +02:00
$post [ 'built' ] = $po -> build ( true );
2014-03-17 23:11:16 +01:00
}
2014-07-19 20:41:48 +02:00
$last_time = $post [ 'time' ];
2014-03-17 23:11:16 +01:00
}
2022-08-29 16:50:45 +02:00
echo mod_page ( _ ( 'Recent posts' ), $config [ 'file_mod_recent_posts' ], array (
2014-07-19 20:41:48 +02:00
'posts' => $posts ,
'limit' => $limit ,
'last_time' => $last_time
2014-03-17 23:11:16 +01:00
)
);
}
2012-05-20 12:20:50 +02:00
2024-08-15 17:05:43 +02:00
function mod_config ( Context $ctx , $board_config = false ) {
2024-08-15 17:12:14 +02:00
global $mod , $board ;
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2013-08-03 12:26:17 +02:00
if ( $board_config && ! openBoard ( $board_config ))
error ( $config [ 'error' ][ 'noboard' ]);
2024-02-23 22:49:23 +01:00
2013-08-03 12:26:17 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'edit_config' ], $board_config ))
2012-05-20 12:20:50 +02:00
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2022-12-10 16:27:59 +01:00
$config_file = $board_config ? $board [ 'dir' ] . 'config.php' : 'inc/secrets.php' ;
2024-02-23 22:49:23 +01:00
2013-08-01 23:18:10 +02:00
if ( $config [ 'mod' ][ 'config_editor_php' ]) {
2013-08-03 12:26:17 +02:00
$readonly = ! ( is_file ( $config_file ) ? is_writable ( $config_file ) : is_writable ( dirname ( $config_file )));
2024-02-23 22:49:23 +01:00
2013-08-01 23:18:10 +02:00
if ( ! $readonly && isset ( $_POST [ 'code' ])) {
$code = $_POST [ 'code' ];
2013-09-21 04:21:05 +02:00
// Save previous instance_config if php_check_syntax fails
$old_code = file_get_contents ( $config_file );
2013-08-03 12:26:17 +02:00
file_put_contents ( $config_file , $code );
2013-09-21 04:21:05 +02:00
$resp = shell_exec_error ( 'php -l ' . $config_file );
if ( preg_match ( '/No syntax errors detected/' , $resp )) {
header ( 'Location: ?/config' . ( $board_config ? '/' . $board_config : '' ), true , $config [ 'redirect_http' ]);
return ;
}
else {
file_put_contents ( $config_file , $old_code );
error ( $config [ 'error' ][ 'badsyntax' ] . $resp );
2024-02-23 22:49:23 +01:00
}
2013-08-01 23:18:10 +02:00
}
2024-02-23 22:49:23 +01:00
2013-08-03 12:26:17 +02:00
$instance_config = @ file_get_contents ( $config_file );
if ( $instance_config === false ) {
$instance_config = " <?php \n \n // This file does not exist yet. You are creating it. " ;
}
2013-08-01 23:18:10 +02:00
$instance_config = str_replace ( " \n " , '
' , utf8tohtml ( $instance_config ));
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Config editor' ), $config [ 'file_mod_config_editor_php' ], array (
2013-08-03 12:26:17 +02:00
'php' => $instance_config ,
'readonly' => $readonly ,
'boards' => listBoards (),
'board' => $board_config ,
2013-09-23 08:48:56 +02:00
'file' => $config_file ,
'token' => make_secure_link_token ( 'config' . ( $board_config ? '/' . $board_config : '' ))
2013-08-03 12:26:17 +02:00
));
2013-08-01 23:18:10 +02:00
return ;
}
2024-02-23 22:49:23 +01:00
2012-05-20 12:20:50 +02:00
require_once 'inc/mod/config-editor.php' ;
2024-02-23 22:49:23 +01:00
2012-05-20 12:20:50 +02:00
$conf = config_vars ();
2024-02-23 22:49:23 +01:00
2012-05-20 12:20:50 +02:00
foreach ( $conf as & $var ) {
if ( is_array ( $var [ 'name' ])) {
$c = & $config ;
foreach ( $var [ 'name' ] as $n )
$c = & $c [ $n ];
} else {
2013-08-03 11:21:02 +02:00
$c = @ $config [ $var [ 'name' ]];
2012-05-20 12:20:50 +02:00
}
2024-02-23 22:49:23 +01:00
2012-05-20 12:20:50 +02:00
$var [ 'value' ] = $c ;
}
unset ( $var );
2024-02-23 22:49:23 +01:00
2012-05-20 12:20:50 +02:00
if ( isset ( $_POST [ 'save' ])) {
$config_append = '' ;
2024-02-23 22:49:23 +01:00
2012-05-20 12:20:50 +02:00
foreach ( $conf as $var ) {
$field_name = 'cf_' . ( is_array ( $var [ 'name' ]) ? implode ( '/' , $var [ 'name' ]) : $var [ 'name' ]);
2024-02-23 22:49:23 +01:00
2012-05-20 12:20:50 +02:00
if ( $var [ 'type' ] == 'boolean' )
$value = isset ( $_POST [ $field_name ]);
elseif ( isset ( $_POST [ $field_name ]))
$value = $_POST [ $field_name ];
else
continue ; // ???
2024-02-23 22:49:23 +01:00
2012-05-20 12:20:50 +02:00
if ( ! settype ( $value , $var [ 'type' ]))
continue ; // invalid
2024-02-23 22:49:23 +01:00
2012-05-20 12:20:50 +02:00
if ( $value != $var [ 'value' ]) {
// This value has been changed.
2024-02-23 22:49:23 +01:00
2012-05-20 12:20:50 +02:00
$config_append .= '$config' ;
2024-02-23 22:49:23 +01:00
2012-05-20 12:20:50 +02:00
if ( is_array ( $var [ 'name' ])) {
foreach ( $var [ 'name' ] as $name )
$config_append .= '[' . var_export ( $name , true ) . ']' ;
} else {
$config_append .= '[' . var_export ( $var [ 'name' ], true ) . ']' ;
}
2024-02-23 22:49:23 +01:00
2013-08-03 11:41:01 +02:00
$config_append .= ' = ' ;
2013-09-08 17:33:51 +02:00
if ( @ $var [ 'permissions' ] && isset ( $config [ 'mod' ][ 'groups' ][ $value ])) {
$config_append .= $config [ 'mod' ][ 'groups' ][ $value ];
2013-08-03 11:41:01 +02:00
} else {
$config_append .= var_export ( $value , true );
}
$config_append .= " ; \n " ;
2012-05-20 12:20:50 +02:00
}
}
2024-02-23 22:49:23 +01:00
2012-05-20 12:22:19 +02:00
if ( ! empty ( $config_append )) {
2012-05-20 12:20:50 +02:00
$config_append = " \n // Changes made via web editor by \" " . $mod [ 'username' ] . " \" @ " . date ( 'r' ) . " : \n " . $config_append . " \n " ;
2013-08-03 12:26:17 +02:00
if ( ! is_file ( $config_file ))
$config_append = " <?php \n \n $config_append " ;
if ( !@ file_put_contents ( $config_file , $config_append , FILE_APPEND )) {
2012-05-20 12:20:50 +02:00
$config_append = htmlentities ( $config_append );
2024-02-23 22:49:23 +01:00
2012-05-20 12:22:19 +02:00
if ( $config [ 'minify_html' ])
2012-05-20 12:20:50 +02:00
$config_append = str_replace ( " \n " , '
' , $config_append );
2024-08-15 17:21:41 +02:00
$page = [];
2012-05-20 12:20:50 +02:00
$page [ 'title' ] = 'Cannot write to file!' ;
$page [ 'config' ] = $config ;
$page [ 'body' ] = '
2013-08-03 12:26:17 +02:00
< p style = " text-align:center " > Tinyboard could not write to < strong > ' . $config_file . ' </ strong > with the ammended configuration , probably due to a permissions error .</ p >
< p style = " text-align:center " > You may proceed with these changes manually by copying and pasting the following code to the end of < strong > ' . $config_file . ' </ strong >:</ p >
2012-05-20 12:20:50 +02:00
< textarea style = " width:700px;height:370px;margin:auto;display:block;background:white;color:black " readonly > ' . $config_append . ' </ textarea >
' ;
2022-08-29 16:50:45 +02:00
echo Element ( $config [ 'file_page_template' ], $page );
2012-05-20 12:20:50 +02:00
exit ;
}
}
2024-02-23 22:49:23 +01:00
2013-09-23 08:48:56 +02:00
header ( 'Location: ?/config' . ( $board_config ? '/' . $board_config : '' ), true , $config [ 'redirect_http' ]);
2024-02-23 22:49:23 +01:00
2012-05-20 12:20:50 +02:00
exit ;
}
2013-09-23 08:48:56 +02:00
2013-08-03 12:26:17 +02:00
mod_page ( _ ( 'Config editor' ) . ( $board_config ? ': ' . sprintf ( $config [ 'board_abbreviation' ], $board_config ) : '' ),
2022-08-29 16:50:45 +02:00
$config [ 'file_mod_config_editor' ], array (
2013-08-03 12:26:17 +02:00
'boards' => listBoards (),
'board' => $board_config ,
'conf' => $conf ,
2013-09-23 08:48:56 +02:00
'file' => $config_file ,
'token' => make_secure_link_token ( 'config' . ( $board_config ? '/' . $board_config : '' ))
2013-08-03 12:26:17 +02:00
));
2012-05-20 12:20:50 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_themes_list ( Context $ctx ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2012-08-12 16:18:13 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'themes' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2012-08-27 13:50:15 +02:00
if ( ! is_dir ( $config [ 'dir' ][ 'themes' ]))
2012-08-12 16:18:13 +02:00
error ( _ ( 'Themes directory doesn\'t exist!' ));
2012-08-27 13:50:15 +02:00
if ( ! $dir = opendir ( $config [ 'dir' ][ 'themes' ]))
2012-08-12 16:18:13 +02:00
error ( _ ( 'Cannot open themes directory; check permissions.' ));
2013-08-01 04:14:26 +02:00
$query = query ( 'SELECT `theme` FROM ``theme_settings`` WHERE `name` IS NULL AND `value` IS NULL' ) or error ( db_error ());
2012-08-12 16:18:13 +02:00
$themes_in_use = $query -> fetchAll ( PDO :: FETCH_COLUMN );
// Scan directory for themes
2024-08-15 17:21:41 +02:00
$themes = [];
2012-08-12 16:18:13 +02:00
while ( $file = readdir ( $dir )) {
if ( $file [ 0 ] != '.' && is_dir ( $config [ 'dir' ][ 'themes' ] . '/' . $file )) {
2024-08-16 18:32:32 +02:00
$themes [ $file ] = Vichan\Functions\Theme\load_theme_config ( $file );
2012-08-12 16:18:13 +02:00
}
}
closedir ( $dir );
2024-02-23 22:49:23 +01:00
2013-09-23 08:48:56 +02:00
foreach ( $themes as $theme_name => & $theme ) {
$theme [ 'rebuild_token' ] = make_secure_link_token ( 'themes/' . $theme_name . '/rebuild' );
$theme [ 'uninstall_token' ] = make_secure_link_token ( 'themes/' . $theme_name . '/uninstall' );
}
2012-08-12 16:18:13 +02:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Manage themes' ), $config [ 'file_mod_themes' ], array (
2012-08-12 16:18:13 +02:00
'themes' => $themes ,
'themes_in_use' => $themes_in_use ,
));
}
2024-08-15 17:05:43 +02:00
function mod_theme_configure ( Context $ctx , $theme_name ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2012-08-12 16:18:13 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'themes' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-08-16 18:32:32 +02:00
if ( ! $theme = Vichan\Functions\Theme\load_theme_config ( $theme_name )) {
2012-08-12 16:18:13 +02:00
error ( $config [ 'error' ][ 'invalidtheme' ]);
}
2012-08-27 13:50:15 +02:00
if ( isset ( $_POST [ 'install' ])) {
2012-08-12 16:18:13 +02:00
// Check if everything is submitted
2012-08-27 13:50:15 +02:00
foreach ( $theme [ 'config' ] as & $conf ) {
if ( ! isset ( $_POST [ $conf [ 'name' ]]) && $conf [ 'type' ] != 'checkbox' )
2012-08-12 16:18:13 +02:00
error ( sprintf ( $config [ 'error' ][ 'required' ], $c [ 'title' ]));
}
2024-02-23 22:49:23 +01:00
2012-08-12 16:18:13 +02:00
// Clear previous settings
2013-08-01 04:14:26 +02:00
$query = prepare ( " DELETE FROM ``theme_settings`` WHERE `theme` = :theme " );
2012-08-12 16:18:13 +02:00
$query -> bindValue ( ':theme' , $theme_name );
$query -> execute () or error ( db_error ( $query ));
2024-02-23 22:49:23 +01:00
2012-08-27 13:50:15 +02:00
foreach ( $theme [ 'config' ] as & $conf ) {
2013-08-01 04:14:26 +02:00
$query = prepare ( " INSERT INTO ``theme_settings`` VALUES(:theme, :name, :value) " );
2012-08-12 16:18:13 +02:00
$query -> bindValue ( ':theme' , $theme_name );
$query -> bindValue ( ':name' , $conf [ 'name' ]);
2013-08-18 18:03:54 +02:00
if ( $conf [ 'type' ] == 'checkbox' )
$query -> bindValue ( ':value' , isset ( $_POST [ $conf [ 'name' ]]) ? 1 : 0 );
else
$query -> bindValue ( ':value' , $_POST [ $conf [ 'name' ]]);
2012-08-12 16:18:13 +02:00
$query -> execute () or error ( db_error ( $query ));
}
2015-04-05 16:59:04 +02:00
2013-08-01 04:14:26 +02:00
$query = prepare ( " INSERT INTO ``theme_settings`` VALUES(:theme, NULL, NULL) " );
2012-08-12 16:18:13 +02:00
$query -> bindValue ( ':theme' , $theme_name );
$query -> execute () or error ( db_error ( $query ));
2015-04-05 16:59:04 +02:00
// Clean cache
Cache :: delete ( " themes " );
2015-04-23 07:57:52 +02:00
Cache :: delete ( " theme_settings_ " . $theme_name );
2024-02-23 22:49:23 +01:00
2012-08-12 16:18:13 +02:00
$result = true ;
$message = false ;
2012-08-27 13:50:15 +02:00
if ( isset ( $theme [ 'install_callback' ])) {
2024-08-16 18:32:32 +02:00
$ret = $theme [ 'install_callback' ]( Vichan\Functions\Theme\theme_settings ( $theme_name ));
2012-08-27 13:50:15 +02:00
if ( $ret && ! empty ( $ret )) {
if ( is_array ( $ret ) && count ( $ret ) == 2 ) {
2012-08-12 16:18:13 +02:00
$result = $ret [ 0 ];
$message = $ret [ 1 ];
}
}
}
2024-02-23 22:49:23 +01:00
2012-08-27 13:50:15 +02:00
if ( ! $result ) {
2012-08-12 16:18:13 +02:00
// Install failed
2013-08-01 04:14:26 +02:00
$query = prepare ( " DELETE FROM ``theme_settings`` WHERE `theme` = :theme " );
2012-08-12 16:18:13 +02:00
$query -> bindValue ( ':theme' , $theme_name );
$query -> execute () or error ( db_error ( $query ));
}
2024-02-23 22:49:23 +01:00
2012-08-12 16:18:13 +02:00
// Build themes
2024-08-16 18:32:32 +02:00
Vichan\Functions\Theme\rebuild_themes ( 'all' );
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( sprintf ( _ ( $result ? 'Installed theme: %s' : 'Installation failed: %s' ), $theme [ 'name' ]), $config [ 'file_mod_theme_installed' ], array (
2012-08-12 16:18:13 +02:00
'theme_name' => $theme_name ,
'theme' => $theme ,
'result' => $result ,
2013-09-23 08:48:56 +02:00
'message' => $message
2012-08-12 16:18:13 +02:00
));
2013-02-28 22:56:44 +01:00
return ;
2012-08-12 16:18:13 +02:00
}
2024-08-16 18:32:32 +02:00
$settings = Vichan\Functions\Theme\theme_settings ( $theme_name );
2012-08-12 16:18:13 +02:00
2022-08-29 16:50:45 +02:00
mod_page ( sprintf ( _ ( 'Configuring theme: %s' ), $theme [ 'name' ]), $config [ 'file_mod_theme_config' ], array (
2012-08-12 16:18:13 +02:00
'theme_name' => $theme_name ,
'theme' => $theme ,
'settings' => $settings ,
2013-09-23 08:48:56 +02:00
'token' => make_secure_link_token ( 'themes/' . $theme_name )
2012-08-12 16:18:13 +02:00
));
}
2024-08-15 17:05:43 +02:00
function mod_theme_uninstall ( Context $ctx , $theme_name ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2012-08-12 16:18:13 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'themes' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2015-04-05 16:59:04 +02:00
2013-08-01 04:14:26 +02:00
$query = prepare ( " DELETE FROM ``theme_settings`` WHERE `theme` = :theme " );
2012-08-12 16:18:13 +02:00
$query -> bindValue ( ':theme' , $theme_name );
$query -> execute () or error ( db_error ( $query ));
2015-04-05 16:59:04 +02:00
// Clean cache
Cache :: delete ( " themes " );
2017-03-30 00:58:11 +02:00
Cache :: delete ( " theme_settings_ " . $theme_name );
2015-04-05 16:59:04 +02:00
2012-08-12 16:18:13 +02:00
header ( 'Location: ?/themes' , true , $config [ 'redirect_http' ]);
}
2024-08-15 17:05:43 +02:00
function mod_theme_rebuild ( Context $ctx , $theme_name ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2012-08-12 16:18:13 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'themes' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2024-08-16 18:32:32 +02:00
Vichan\Functions\Theme\rebuild_theme ( $theme_name , 'all' );
2012-08-12 16:18:13 +02:00
2022-08-29 16:50:45 +02:00
mod_page ( sprintf ( _ ( 'Rebuilt theme: %s' ), $theme_name ), $config [ 'file_mod_theme_rebuilt' ], array (
2012-08-12 16:18:13 +02:00
'theme_name' => $theme_name ,
));
}
2013-01-25 12:18:03 +01:00
2015-03-29 03:18:14 +02:00
// This needs to be done for `secure` CSRF prevention compatibility, otherwise the $board will be read in as the token if editing global pages.
function delete_page_base ( $page = '' , $board = false ) {
global $config , $mod ;
if ( empty ( $board ))
$board = false ;
if ( ! $board && $mod [ 'boards' ][ 0 ] !== '*' )
error ( $config [ 'error' ][ 'noaccess' ]);
if ( ! hasPermission ( $config [ 'mod' ][ 'edit_pages' ], $board ))
error ( $config [ 'error' ][ 'noaccess' ]);
if ( $board !== FALSE && ! openBoard ( $board ))
error ( $config [ 'error' ][ 'noboard' ]);
if ( $board ) {
$query = prepare ( 'DELETE FROM ``pages`` WHERE `board` = :board AND `name` = :name' );
$query -> bindValue ( ':board' , ( $board ? $board : NULL ));
} else {
$query = prepare ( 'DELETE FROM ``pages`` WHERE `board` IS NULL AND `name` = :name' );
}
$query -> bindValue ( ':name' , $page );
$query -> execute () or error ( db_error ( $query ));
header ( 'Location: ?/edit_pages' . ( $board ? ( '/' . $board ) : '' ), true , $config [ 'redirect_http' ]);
}
2024-08-15 17:05:43 +02:00
function mod_delete_page ( Context $ctx , $page = '' ) {
delete_page_base ( $ctx , $page );
2015-03-29 03:18:14 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_delete_page_board ( Context $ctx , $page = '' , $board = false ) {
delete_page_base ( $ctx , $page , $board );
2015-03-29 03:18:14 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_edit_page ( Context $ctx , $id ) {
2024-08-15 17:12:14 +02:00
global $mod , $board ;
$config = $ctx -> get ( 'config' );
2015-03-29 03:18:14 +02:00
$query = prepare ( 'SELECT * FROM ``pages`` WHERE `id` = :id' );
$query -> bindValue ( ':id' , $id );
$query -> execute () or error ( db_error ( $query ));
$page = $query -> fetch ();
2024-02-23 22:49:23 +01:00
2015-03-29 03:18:14 +02:00
if ( ! $page )
error ( _ ( 'Could not find the page you are trying to edit.' ));
if ( ! $page [ 'board' ] && $mod [ 'boards' ][ 0 ] !== '*' )
error ( $config [ 'error' ][ 'noaccess' ]);
if ( ! hasPermission ( $config [ 'mod' ][ 'edit_pages' ], $page [ 'board' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
if ( $page [ 'board' ] && ! openBoard ( $page [ 'board' ]))
error ( $config [ 'error' ][ 'noboard' ]);
if ( isset ( $_POST [ 'method' ], $_POST [ 'content' ])) {
$content = $_POST [ 'content' ];
$method = $_POST [ 'method' ];
$page [ 'type' ] = $method ;
2024-02-23 22:49:23 +01:00
2015-03-29 03:18:14 +02:00
if ( ! in_array ( $method , array ( 'markdown' , 'html' , 'infinity' )))
error ( _ ( 'Unrecognized page markup method.' ));
2024-02-23 22:49:23 +01:00
2015-03-29 03:18:14 +02:00
switch ( $method ) {
2024-02-23 22:49:23 +01:00
case 'markdown' :
2015-03-29 03:18:14 +02:00
$write = markdown ( $content );
break ;
case 'html' :
if ( hasPermission ( $config [ 'mod' ][ 'rawhtml' ])) {
$write = $content ;
} else {
$write = purify_html ( $content );
}
break ;
case 'infinity' :
$c = $content ;
markup ( $content );
$write = $content ;
$content = $c ;
}
if ( ! isset ( $write ) or ! $write )
error ( _ ( 'Failed to mark up your input for some reason...' ));
$query = prepare ( 'UPDATE ``pages`` SET `type` = :method, `content` = :content WHERE `id` = :id' );
$query -> bindValue ( ':method' , $method );
$query -> bindValue ( ':content' , $content );
$query -> bindValue ( ':id' , $id );
$query -> execute () or error ( db_error ( $query ));
2022-08-20 18:17:04 +02:00
$fn = ( isset ( $board [ 'uri' ]) ? ( $board [ 'uri' ] . '/' ) : '' ) . $page [ 'name' ] . '.html' ;
2015-03-29 03:18:14 +02:00
$body = " <div class='ban'> $write </div> " ;
2022-08-29 16:50:45 +02:00
$html = Element ( $config [ 'file_page_template' ], array ( 'config' => $config , 'boardlist' => createBoardlist (), 'body' => $body , 'title' => utf8tohtml ( $page [ 'title' ])));
2015-03-29 03:18:14 +02:00
file_write ( $fn , $html );
}
if ( ! isset ( $content )) {
$query = prepare ( 'SELECT `content` FROM ``pages`` WHERE `id` = :id' );
$query -> bindValue ( ':id' , $id );
$query -> execute () or error ( db_error ( $query ));
$content = $query -> fetchColumn ();
}
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( sprintf ( _ ( 'Editing static page: %s' ), $page [ 'name' ]), $config [ 'file_mod_edit_page' ], array ( 'page' => $page , 'token' => make_secure_link_token ( " edit_page/ $id " ), 'content' => prettify_textarea ( $content ), 'board' => $board ));
2015-03-29 03:18:14 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_pages ( Context $ctx , $board = false ) {
2024-08-15 17:12:14 +02:00
global $mod , $pdo ;
$config = $ctx -> get ( 'config' );
2015-03-29 03:18:14 +02:00
if ( empty ( $board ))
$board = false ;
if ( ! $board && $mod [ 'boards' ][ 0 ] !== '*' )
error ( $config [ 'error' ][ 'noaccess' ]);
if ( ! hasPermission ( $config [ 'mod' ][ 'edit_pages' ], $board ))
error ( $config [ 'error' ][ 'noaccess' ]);
if ( $board !== FALSE && ! openBoard ( $board ))
error ( $config [ 'error' ][ 'noboard' ]);
if ( $board ) {
$query = prepare ( 'SELECT * FROM ``pages`` WHERE `board` = :board' );
$query -> bindValue ( ':board' , $board );
} else {
$query = query ( 'SELECT * FROM ``pages`` WHERE `board` IS NULL' );
}
$query -> execute () or error ( db_error ( $query ));
$pages = $query -> fetchAll ( PDO :: FETCH_ASSOC );
if ( isset ( $_POST [ 'page' ])) {
if ( $board and sizeof ( $pages ) > $config [ 'pages_max' ])
error ( sprintf ( _ ( 'Sorry, this site only allows %d pages per board.' ), $config [ 'pages_max' ]));
if ( ! preg_match ( '/^[a-z0-9]{1,255}$/' , $_POST [ 'page' ]))
error ( _ ( 'Page names must be < 255 chars and may only contain lowercase letters A-Z and digits 1-9.' ));
foreach ( $pages as $i => $p ) {
if ( $_POST [ 'page' ] === $p [ 'name' ])
error ( _ ( 'Refusing to create a new page with the same name as an existing one.' ));
}
$title = ( $_POST [ 'title' ] ? $_POST [ 'title' ] : NULL );
$query = prepare ( 'INSERT INTO ``pages``(board, title, name) VALUES(:board, :title, :name)' );
$query -> bindValue ( ':board' , ( $board ? $board : NULL ));
$query -> bindValue ( ':title' , $title );
$query -> bindValue ( ':name' , $_POST [ 'page' ]);
$query -> execute () or error ( db_error ( $query ));
$pages [] = array ( 'id' => $pdo -> lastInsertId (), 'name' => $_POST [ 'page' ], 'board' => $board , 'title' => $title );
}
foreach ( $pages as $i => & $p ) {
$p [ 'delete_token' ] = make_secure_link_token ( 'edit_pages/delete/' . $p [ 'name' ] . ( $board ? ( '/' . $board ) : '' ));
}
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Pages' ), $config [ 'file_mod_pages' ], array ( 'pages' => $pages , 'token' => make_secure_link_token ( 'edit_pages' . ( $board ? ( '/' . $board ) : '' )), 'board' => $board ));
2015-03-29 03:18:14 +02:00
}
2024-08-15 17:05:43 +02:00
function mod_debug_antispam ( Context $ctx ) {
2013-01-25 12:18:03 +01:00
global $pdo , $config ;
2024-02-23 22:49:23 +01:00
2024-08-15 17:21:41 +02:00
$args = [];
2024-02-23 22:49:23 +01:00
2013-01-25 12:18:03 +01:00
if ( isset ( $_POST [ 'board' ], $_POST [ 'thread' ])) {
$where = '`board` = ' . $pdo -> quote ( $_POST [ 'board' ]);
if ( $_POST [ 'thread' ] != '' )
$where .= ' AND `thread` = ' . $pdo -> quote ( $_POST [ 'thread' ]);
2024-02-23 22:49:23 +01:00
2013-01-25 12:18:03 +01:00
if ( isset ( $_POST [ 'purge' ])) {
2013-08-01 04:14:26 +02:00
$query = prepare ( ', DATE ``antispam`` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE' . $where );
2013-01-25 12:18:03 +01:00
$query -> bindValue ( ':expires' , $config [ 'spam' ][ 'hidden_inputs_expire' ]);
$query -> execute () or error ( db_error ());
}
2024-02-23 22:49:23 +01:00
2013-01-25 12:18:03 +01:00
$args [ 'board' ] = $_POST [ 'board' ];
$args [ 'thread' ] = $_POST [ 'thread' ];
} else {
$where = '' ;
}
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = query ( 'SELECT COUNT(*) FROM ``antispam``' . ( $where ? " WHERE $where " : '' )) or error ( db_error ());
2013-08-01 02:51:43 +02:00
$args [ 'total' ] = number_format ( $query -> fetchColumn ());
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = query ( 'SELECT COUNT(*) FROM ``antispam`` WHERE `expires` IS NOT NULL' . ( $where ? " AND $where " : '' )) or error ( db_error ());
2013-08-01 02:51:43 +02:00
$args [ 'expiring' ] = number_format ( $query -> fetchColumn ());
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = query ( 'SELECT * FROM ``antispam`` ' . ( $where ? " WHERE $where " : '' ) . ' ORDER BY `passed` DESC LIMIT 40' ) or error ( db_error ());
2013-01-25 12:18:03 +01:00
$args [ 'top' ] = $query -> fetchAll ( PDO :: FETCH_ASSOC );
2024-02-23 22:49:23 +01:00
2013-08-01 04:14:26 +02:00
$query = query ( 'SELECT * FROM ``antispam`` ' . ( $where ? " WHERE $where " : '' ) . ' ORDER BY `created` DESC LIMIT 20' ) or error ( db_error ());
2013-01-25 12:18:03 +01:00
$args [ 'recent' ] = $query -> fetchAll ( PDO :: FETCH_ASSOC );
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Debug: Anti-spam' ), $config [ 'file_mod_debug_antispam' ], $args );
2013-01-25 12:18:03 +01:00
}
2024-08-15 17:05:43 +02:00
function mod_debug_recent_posts ( Context $ctx ) {
2013-01-25 12:18:03 +01:00
global $pdo , $config ;
2024-02-23 22:49:23 +01:00
2013-01-25 12:23:26 +01:00
$limit = 500 ;
2024-02-23 22:49:23 +01:00
2013-01-25 12:18:03 +01:00
$boards = listBoards ();
2024-02-23 22:49:23 +01:00
2013-01-25 12:18:03 +01:00
// Manually build an SQL query
$query = 'SELECT * FROM (' ;
foreach ( $boards as $board ) {
2013-08-01 04:14:26 +02:00
$query .= sprintf ( 'SELECT *, %s AS `board` FROM ``posts_%s`` UNION ALL ' , $pdo -> quote ( $board [ 'uri' ]), $board [ 'uri' ]);
2013-01-25 12:18:03 +01:00
}
// Remove the last "UNION ALL" seperator and complete the query
$query = preg_replace ( '/UNION ALL $/' , ') AS `all_posts` ORDER BY `time` DESC LIMIT ' . $limit , $query );
$query = query ( $query ) or error ( db_error ());
$posts = $query -> fetchAll ( PDO :: FETCH_ASSOC );
2024-02-23 22:49:23 +01:00
2013-09-09 12:16:13 +02:00
// Fetch recent posts from flood prevention cache
$query = query ( " SELECT * FROM ``flood`` ORDER BY `time` DESC " ) or error ( db_error ());
$flood_posts = $query -> fetchAll ( PDO :: FETCH_ASSOC );
2024-02-23 22:49:23 +01:00
2013-01-25 12:18:03 +01:00
foreach ( $posts as & $post ) {
$post [ 'snippet' ] = pm_snippet ( $post [ 'body' ]);
2013-09-09 12:16:13 +02:00
foreach ( $flood_posts as $flood_post ) {
if ( $flood_post [ 'time' ] == $post [ 'time' ] &&
$flood_post [ 'posthash' ] == make_comment_hex ( $post [ 'body_nomarkup' ]) &&
$flood_post [ 'filehash' ] == $post [ 'filehash' ])
$post [ 'in_flood_table' ] = true ;
}
2013-01-25 12:18:03 +01:00
}
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Debug: Recent posts' ), $config [ 'file_mod_debug_recent_posts' ], array ( 'posts' => $posts , 'flood_posts' => $flood_posts ));
2013-01-25 12:18:03 +01:00
}
2024-08-15 17:05:43 +02:00
function mod_debug_sql ( Context $ctx ) {
2024-08-15 17:12:14 +02:00
$config = $ctx -> get ( 'config' );
2024-02-23 22:49:23 +01:00
2013-01-25 13:56:55 +01:00
if ( ! hasPermission ( $config [ 'mod' ][ 'debug_sql' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
2024-02-23 22:49:23 +01:00
2013-01-25 13:56:55 +01:00
$args [ 'security_token' ] = make_secure_link_token ( 'debug/sql' );
2024-02-23 22:49:23 +01:00
2013-01-25 13:56:55 +01:00
if ( isset ( $_POST [ 'query' ])) {
$args [ 'query' ] = $_POST [ 'query' ];
if ( $query = query ( $_POST [ 'query' ])) {
$args [ 'result' ] = $query -> fetchAll ( PDO :: FETCH_ASSOC );
if ( ! empty ( $args [ 'result' ]))
$args [ 'keys' ] = array_keys ( $args [ 'result' ][ 0 ]);
else
$args [ 'result' ] = 'empty' ;
} else {
$args [ 'error' ] = db_error ();
}
}
2024-02-23 22:49:23 +01:00
2022-08-29 16:50:45 +02:00
mod_page ( _ ( 'Debug: SQL' ), $config [ 'file_mod_debug_sql' ], $args );
2013-01-25 13:56:55 +01:00
}