1
0
mirror of https://github.com/vichan-devel/vichan.git synced 2024-11-27 17:00:52 +01:00

Merge pull request #685 from Zankaria/remove-cache-backends

Remove cache backends
This commit is contained in:
Lorenzo Yario 2024-03-11 15:58:35 -07:00 committed by GitHub
commit 4e707ab9ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 132 additions and 183 deletions

View File

@ -34,7 +34,7 @@ Requirements
------------ ------------
1. PHP >= 7.4 1. PHP >= 7.4
2. MySQL/MariaDB server 2. MySQL/MariaDB server
3. [mbstring](http://www.php.net/manual/en/mbstring.installation.php) 3. [mbstring](http://www.php.net/manual/en/mbstring.installation.php)
4. [PHP GD](http://www.php.net/manual/en/intro.image.php) 4. [PHP GD](http://www.php.net/manual/en/intro.image.php)
5. [PHP PDO](http://www.php.net/manual/en/intro.pdo.php) 5. [PHP PDO](http://www.php.net/manual/en/intro.pdo.php)
6. A Unix-like OS, preferrably FreeBSD or GNU/Linux 6. A Unix-like OS, preferrably FreeBSD or GNU/Linux
@ -44,9 +44,7 @@ We try to make sure vichan is compatible with all major web servers. vichan does
### Recommended ### Recommended
1. MySQL/MariaDB server >= 5.5.3 1. MySQL/MariaDB server >= 5.5.3
2. ImageMagick (command-line ImageMagick or GraphicsMagick preferred). 2. ImageMagick (command-line ImageMagick or GraphicsMagick preferred).
3. ~~[APC (Alternative PHP Cache)](http://php.net/manual/en/book.apc.php)~~, 3. [APCu (Alternative PHP Cache)](http://php.net/manual/en/book.apcu.php),
[APCu (Alternative PHP Cache)](http://php.net/manual/en/book.apcu.php),
[XCache](http://xcache.lighttpd.net/),
[Memcached](http://www.php.net/manual/en/intro.memcached.php) or [Memcached](http://www.php.net/manual/en/intro.memcached.php) or
[Redis](https://redis.io/docs/about/) [Redis](https://redis.io/docs/about/)
@ -63,7 +61,7 @@ Installation
git clone git://github.com/vichan-devel/vichan.git git clone git://github.com/vichan-devel/vichan.git
2. run ```composer install``` inside the directory 2. run ```composer install``` inside the directory
3. Navigate to ```install.php``` in your web browser and follow the 3. Navigate to ```install.php``` in your web browser and follow the
prompts. prompts.
4. vichan should now be installed. Log in to ```mod.php``` with the 4. vichan should now be installed. Log in to ```mod.php``` with the

View File

@ -10,7 +10,7 @@ class Cache {
private static $cache; private static $cache;
public static function init() { public static function init() {
global $config; global $config;
switch ($config['cache']['enabled']) { switch ($config['cache']['enabled']) {
case 'memcached': case 'memcached':
self::$cache = new Memcached(); self::$cache = new Memcached();
@ -31,9 +31,9 @@ class Cache {
} }
public static function get($key) { public static function get($key) {
global $config, $debug; global $config, $debug;
$key = $config['cache']['prefix'] . $key; $key = $config['cache']['prefix'] . $key;
$data = false; $data = false;
switch ($config['cache']['enabled']) { switch ($config['cache']['enabled']) {
case 'memcached': case 'memcached':
@ -41,15 +41,9 @@ class Cache {
self::init(); self::init();
$data = self::$cache->get($key); $data = self::$cache->get($key);
break; break;
case 'apc':
$data = apc_fetch($key);
break;
case 'apcu': case 'apcu':
$data = apcu_fetch($key); $data = apcu_fetch($key);
break; break;
case 'xcache':
$data = xcache_get($key);
break;
case 'php': case 'php':
$data = isset(self::$cache[$key]) ? self::$cache[$key] : false; $data = isset(self::$cache[$key]) ? self::$cache[$key] : false;
break; break;
@ -70,20 +64,20 @@ class Cache {
$data = json_decode(self::$cache->get($key), true); $data = json_decode(self::$cache->get($key), true);
break; break;
} }
if ($config['debug']) if ($config['debug'])
$debug['cached'][] = $key . ($data === false ? ' (miss)' : ' (hit)'); $debug['cached'][] = $key . ($data === false ? ' (miss)' : ' (hit)');
return $data; return $data;
} }
public static function set($key, $value, $expires = false) { public static function set($key, $value, $expires = false) {
global $config, $debug; global $config, $debug;
$key = $config['cache']['prefix'] . $key; $key = $config['cache']['prefix'] . $key;
if (!$expires) if (!$expires)
$expires = $config['cache']['timeout']; $expires = $config['cache']['timeout'];
switch ($config['cache']['enabled']) { switch ($config['cache']['enabled']) {
case 'memcached': case 'memcached':
if (!self::$cache) if (!self::$cache)
@ -95,15 +89,9 @@ class Cache {
self::init(); self::init();
self::$cache->setex($key, $expires, json_encode($value)); self::$cache->setex($key, $expires, json_encode($value));
break; break;
case 'apc':
apc_store($key, $value, $expires);
break;
case 'apcu': case 'apcu':
apcu_store($key, $value, $expires); apcu_store($key, $value, $expires);
break; break;
case 'xcache':
xcache_set($key, $value, $expires);
break;
case 'fs': case 'fs':
$key = str_replace('/', '::', $key); $key = str_replace('/', '::', $key);
$key = str_replace("\0", '', $key); $key = str_replace("\0", '', $key);
@ -113,15 +101,15 @@ class Cache {
self::$cache[$key] = $value; self::$cache[$key] = $value;
break; break;
} }
if ($config['debug']) if ($config['debug'])
$debug['cached'][] = $key . ' (set)'; $debug['cached'][] = $key . ' (set)';
} }
public static function delete($key) { public static function delete($key) {
global $config, $debug; global $config, $debug;
$key = $config['cache']['prefix'] . $key; $key = $config['cache']['prefix'] . $key;
switch ($config['cache']['enabled']) { switch ($config['cache']['enabled']) {
case 'memcached': case 'memcached':
if (!self::$cache) if (!self::$cache)
@ -133,15 +121,9 @@ class Cache {
self::init(); self::init();
self::$cache->del($key); self::$cache->del($key);
break; break;
case 'apc':
apc_delete($key);
break;
case 'apcu': case 'apcu':
apcu_delete($key); apcu_delete($key);
break; break;
case 'xcache':
xcache_unset($key);
break;
case 'fs': case 'fs':
$key = str_replace('/', '::', $key); $key = str_replace('/', '::', $key);
$key = str_replace("\0", '', $key); $key = str_replace("\0", '', $key);
@ -151,20 +133,18 @@ class Cache {
unset(self::$cache[$key]); unset(self::$cache[$key]);
break; break;
} }
if ($config['debug']) if ($config['debug'])
$debug['cached'][] = $key . ' (deleted)'; $debug['cached'][] = $key . ' (deleted)';
} }
public static function flush() { public static function flush() {
global $config; global $config;
switch ($config['cache']['enabled']) { switch ($config['cache']['enabled']) {
case 'memcached': case 'memcached':
if (!self::$cache) if (!self::$cache)
self::init(); self::init();
return self::$cache->flush(); return self::$cache->flush();
case 'apc':
return apc_clear_cache('user');
case 'apcu': case 'apcu':
return apcu_clear_cache('user'); return apcu_clear_cache('user');
case 'php': case 'php':
@ -181,7 +161,7 @@ class Cache {
self::init(); self::init();
return self::$cache->flushDB(); return self::$cache->flushDB();
} }
return false; return false;
} }
} }

View File

@ -2,7 +2,7 @@
/* /*
* Copyright (c) 2010-2013 Tinyboard Development Group * Copyright (c) 2010-2013 Tinyboard Development Group
* *
* WARNING: This is a project-wide configuration file and is overwritten when upgrading to a newer * WARNING: This is a project-wide configuration file and is overwritten when upgrading to a newer
* version of vichan. Please leave this file unchanged, or it will be a lot harder for you to upgrade. * version of vichan. Please leave this file unchanged, or it will be a lot harder for you to upgrade.
* If you would like to make instance-specific changes to your own setup, please use secrets.php. * If you would like to make instance-specific changes to your own setup, please use secrets.php.
@ -114,15 +114,14 @@
/* /*
* On top of the static file caching system, you can enable the additional caching system which is * On top of the static file caching system, you can enable the additional caching system which is
* designed to minimize SQL queries and can significantly increase speed when posting or using the * designed to minimize SQL queries and can significantly increase speed when posting or using the
* moderator interface. APC is the recommended method of caching. * moderator interface. APC is the recommended method of caching.
* *
* https://github.com/vichan-devel/vichan/wiki/cache * https://github.com/vichan-devel/vichan/wiki/cache
*/ */
$config['cache']['enabled'] = 'php'; $config['cache']['enabled'] = 'php';
// $config['cache']['enabled'] = 'xcache'; // $config['cache']['enabled'] = 'apcu';
// $config['cache']['enabled'] = 'apc';
// $config['cache']['enabled'] = 'memcached'; // $config['cache']['enabled'] = 'memcached';
// $config['cache']['enabled'] = 'redis'; // $config['cache']['enabled'] = 'redis';
// $config['cache']['enabled'] = 'fs'; // $config['cache']['enabled'] = 'fs';
@ -202,7 +201,7 @@
// Prevents most Tor exit nodes from making posts. Recommended, as a lot of abuse comes from Tor because // Prevents most Tor exit nodes from making posts. Recommended, as a lot of abuse comes from Tor because
// of the strong anonymity associated with it. // of the strong anonymity associated with it.
// Example: $config['dnsbl'][] = 'another.blacklist.net'; // Example: $config['dnsbl'][] = 'another.blacklist.net';
// $config['dnsbl'][] = array('tor.dnsbl.sectoor.de', 1); //sectoor.de site is dead. the number stands for (an) ip adress(es) I guess. // $config['dnsbl'][] = array('tor.dnsbl.sectoor.de', 1); //sectoor.de site is dead. the number stands for (an) ip adress(es) I guess.
// Replacement for sectoor.de // Replacement for sectoor.de
$config['dnsbl'][] = array('rbl.efnetrbl.org', 4); $config['dnsbl'][] = array('rbl.efnetrbl.org', 4);
@ -213,22 +212,22 @@
// http://www.projecthoneypot.org/httpbl.php // http://www.projecthoneypot.org/httpbl.php
// $config['dnsbl'][] = array('<your access key>.%.dnsbl.httpbl.org', function($ip) { // $config['dnsbl'][] = array('<your access key>.%.dnsbl.httpbl.org', function($ip) {
// $octets = explode('.', $ip); // $octets = explode('.', $ip);
// //
// // days since last activity // // days since last activity
// if ($octets[1] > 14) // if ($octets[1] > 14)
// return false; // return false;
// //
// // "threat score" (http://www.projecthoneypot.org/threat_info.php) // // "threat score" (http://www.projecthoneypot.org/threat_info.php)
// if ($octets[2] < 5) // if ($octets[2] < 5)
// return false; // return false;
// //
// return true; // return true;
// }, 'dnsbl.httpbl.org'); // hide our access key // }, 'dnsbl.httpbl.org'); // hide our access key
// Skip checking certain IP addresses against blacklists (for troubleshooting or whatever) // Skip checking certain IP addresses against blacklists (for troubleshooting or whatever)
$config['dnsbl_exceptions'][] = '127.0.0.1'; $config['dnsbl_exceptions'][] = '127.0.0.1';
// To prevent bump attacks; returns the thread to last position after the last post is deleted. // To prevent bump attacks; returns the thread to last position after the last post is deleted.
$config['anti_bump_flood'] = false; $config['anti_bump_flood'] = false;
/* /*
@ -321,7 +320,7 @@
$config['hcaptcha_public'] = '7a4b21e0-dc53-46f2-a9f8-91d2e74b63a0'; $config['hcaptcha_public'] = '7a4b21e0-dc53-46f2-a9f8-91d2e74b63a0';
$config['hcaptcha_private'] = '0x4e9A01bE637b51dC41a7Ea9865C3fDe4aB72Cf17'; $config['hcaptcha_private'] = '0x4e9A01bE637b51dC41a7Ea9865C3fDe4aB72Cf17';
// Enable Custom Captcha you need to change a couple of settings // Enable Custom Captcha you need to change a couple of settings
//Read more at: /inc/captcha/readme.md //Read more at: /inc/captcha/readme.md
$config['captcha'] = array(); $config['captcha'] = array();
@ -329,7 +328,7 @@
$config['captcha']['enabled'] = false; $config['captcha']['enabled'] = false;
//New thread captcha //New thread captcha
//Require solving a captcha to post a thread. //Require solving a captcha to post a thread.
//Default off. //Default off.
$config['new_thread_capt'] = false; $config['new_thread_capt'] = false;
@ -340,7 +339,7 @@
// Custom captcha extra field (eg. charset) // Custom captcha extra field (eg. charset)
$config['captcha']['extra'] = 'abcdefghijklmnopqrstuvwxyz'; $config['captcha']['extra'] = 'abcdefghijklmnopqrstuvwxyz';
// Ability to lock a board for normal users and still allow mods to post. Could also be useful for making an archive board // Ability to lock a board for normal users and still allow mods to post. Could also be useful for making an archive board
$config['board_locked'] = false; $config['board_locked'] = false;
@ -478,7 +477,7 @@
// ), // ),
// 'action' => 'reject' // 'action' => 'reject'
// ); // );
// Filter flood prevention conditions ("flood-match") depend on a table which contains a cache of recent // Filter flood prevention conditions ("flood-match") depend on a table which contains a cache of recent
// posts across all boards. This table is automatically purged of older posts, determining the maximum // posts across all boards. This table is automatically purged of older posts, determining the maximum
// "age" by looking at each filter. However, when determining the maximum age, vichan does not look // "age" by looking at each filter. However, when determining the maximum age, vichan does not look
@ -570,9 +569,9 @@
$config['markup_urls'] = true; $config['markup_urls'] = true;
// Optional URL prefix for links (eg. "http://anonym.to/?"). // Optional URL prefix for links (eg. "http://anonym.to/?").
$config['link_prefix'] = ''; $config['link_prefix'] = '';
$config['url_ads'] = &$config['link_prefix']; // leave alias $config['url_ads'] = &$config['link_prefix']; // leave alias
// Allow "uploading" images via URL as well. Users can enter the URL of the image and then vichan will // Allow "uploading" images via URL as well. Users can enter the URL of the image and then vichan will
// download it. Not usually recommended. // download it. Not usually recommended.
$config['allow_upload_by_url'] = false; $config['allow_upload_by_url'] = false;
@ -591,7 +590,7 @@
// as they are submitted and changes or censors particular words or phrases. // as they are submitted and changes or censors particular words or phrases.
// For a normal string replacement: // For a normal string replacement:
// $config['wordfilters'][] = array('cat', 'dog'); // $config['wordfilters'][] = array('cat', 'dog');
// Advanced raplcement (regular expressions): // Advanced raplcement (regular expressions):
// $config['wordfilters'][] = array('/ca[rt]/', 'dog', true); // 'true' means it's a regular expression // $config['wordfilters'][] = array('/ca[rt]/', 'dog', true); // 'true' means it's a regular expression
@ -734,10 +733,10 @@
// $config['additional_javascript'][] = 'js/multi-image.js'; // $config['additional_javascript'][] = 'js/multi-image.js';
$config['max_images'] = 1; $config['max_images'] = 1;
// Method to use for determing the max filesize. // Method to use for determing the max filesize.
// "split" means that your max filesize is split between the images. For example, if your max filesize // "split" means that your max filesize is split between the images. For example, if your max filesize
// is 2MB, the filesizes of all files must add up to 2MB for it to work. // is 2MB, the filesizes of all files must add up to 2MB for it to work.
// "each" means that each file can be 2MB, so if your max_images is 3, each post could contain 6MB of // "each" means that each file can be 2MB, so if your max_images is 3, each post could contain 6MB of
// images. "split" is recommended. // images. "split" is recommended.
$config['multiimage_method'] = 'split'; $config['multiimage_method'] = 'split';
@ -764,7 +763,7 @@
* 'gd' PHP GD (default). Only handles the most basic image formats (GIF, JPEG, PNG). * 'gd' PHP GD (default). Only handles the most basic image formats (GIF, JPEG, PNG).
* GD is a prerequisite for vichan no matter what method you choose. * GD is a prerequisite for vichan no matter what method you choose.
* *
* 'imagick' PHP's ImageMagick bindings. Fast and efficient, supporting many image formats. * 'imagick' PHP's ImageMagick bindings. Fast and efficient, supporting many image formats.
* A few minor bugs. http://pecl.php.net/package/imagick * A few minor bugs. http://pecl.php.net/package/imagick
* *
* 'convert' The command line version of ImageMagick (`convert`). Fixes most of the bugs in * 'convert' The command line version of ImageMagick (`convert`). Fixes most of the bugs in
@ -790,12 +789,12 @@
// Use the command-line `exiftool` tool to strip EXIF metadata without decompressing/recompressing JPEGs. // Use the command-line `exiftool` tool to strip EXIF metadata without decompressing/recompressing JPEGs.
// Ignored when $config['redraw_image'] is true. // Ignored when $config['redraw_image'] is true.
$config['use_exiftool'] = false; $config['use_exiftool'] = false;
// Redraw the image to strip any excess data (commonly ZIP archives) WARNING: This might strip the // Redraw the image to strip any excess data (commonly ZIP archives) WARNING: This might strip the
// animation of GIFs, depending on the chosen thumbnailing method. It also requires recompressing // animation of GIFs, depending on the chosen thumbnailing method. It also requires recompressing
// the image, so more processing power is required. // the image, so more processing power is required.
$config['redraw_image'] = false; $config['redraw_image'] = false;
// Automatically correct the orientation of JPEG files using -auto-orient in `convert`. This only works // Automatically correct the orientation of JPEG files using -auto-orient in `convert`. This only works
// when `convert` or `gm` is selected for thumbnailing. Again, requires more processing power because // when `convert` or `gm` is selected for thumbnailing. Again, requires more processing power because
// this basically does the same thing as $config['redraw_image']. (If $config['redraw_image'] is enabled, // this basically does the same thing as $config['redraw_image']. (If $config['redraw_image'] is enabled,
@ -880,7 +879,7 @@
$config['image_identification_yandex'] = true; $config['image_identification_yandex'] = true;
// Anime/manga search engine. // Anime/manga search engine.
$config['image_identification_iqdb'] = false; $config['image_identification_iqdb'] = false;
// Set this to true if you're using a BSD // Set this to true if you're using a BSD
$config['bsd_md5'] = false; $config['bsd_md5'] = false;
@ -1307,7 +1306,6 @@
$config['file_mod_debug_antispam'] = 'mod/debug/antispam.html'; $config['file_mod_debug_antispam'] = 'mod/debug/antispam.html';
$config['file_mod_debug_recent_posts'] = 'mod/debug/recent_posts.html'; $config['file_mod_debug_recent_posts'] = 'mod/debug/recent_posts.html';
$config['file_mod_debug_sql'] = 'mod/debug/sql.html'; $config['file_mod_debug_sql'] = 'mod/debug/sql.html';
$config['file_mod_debug_apc'] = 'mod/debug/apc.html';
// Board directory, followed by a forward-slash (/). // Board directory, followed by a forward-slash (/).
$config['board_path'] = '%s/'; $config['board_path'] = '%s/';
@ -1352,7 +1350,7 @@
// Website favicon. // Website favicon.
// $config['url_favicon'] = '/favicon.gif'; // $config['url_favicon'] = '/favicon.gif';
// Try not to build pages when we shouldn't have to. // Try not to build pages when we shouldn't have to.
$config['try_smarter'] = true; $config['try_smarter'] = true;
@ -1708,8 +1706,6 @@
$config['mod']['news_delete'] = ADMIN; $config['mod']['news_delete'] = ADMIN;
// Execute un-filtered SQL queries on the database (?/debug/sql) // Execute un-filtered SQL queries on the database (?/debug/sql)
$config['mod']['debug_sql'] = DISABLED; $config['mod']['debug_sql'] = DISABLED;
// Look through all cache values for debugging when APC is enabled (?/debug/apc)
$config['mod']['debug_apc'] = ADMIN;
// Edit the current configuration (via web interface) // Edit the current configuration (via web interface)
$config['mod']['edit_config'] = ADMIN; $config['mod']['edit_config'] = ADMIN;
// View ban appeals // View ban appeals
@ -1734,21 +1730,21 @@
'convert_args', 'convert_args',
'db>password', 'db>password',
); );
$config['mod']['config'][JANITOR] = array( $config['mod']['config'][JANITOR] = array(
'!', // Allow editing ONLY the variables listed (in this case, nothing). '!', // Allow editing ONLY the variables listed (in this case, nothing).
); );
$config['mod']['config'][MOD] = array( $config['mod']['config'][MOD] = array(
'!', // Allow editing ONLY the variables listed (plus that in $config['mod']['config'][JANITOR]). '!', // Allow editing ONLY the variables listed (plus that in $config['mod']['config'][JANITOR]).
'global_message', 'global_message',
); );
// Example: Disallow ADMIN from editing (and viewing) $config['db']['password']. // Example: Disallow ADMIN from editing (and viewing) $config['db']['password'].
// $config['mod']['config'][ADMIN] = array( // $config['mod']['config'][ADMIN] = array(
// 'db>password', // 'db>password',
// ); // );
// Example: Allow ADMIN to edit anything other than $config['db'] // Example: Allow ADMIN to edit anything other than $config['db']
// (and $config['mod']['config'][DISABLED]). // (and $config['mod']['config'][DISABLED]).
// $config['mod']['config'][ADMIN] = array( // $config['mod']['config'][ADMIN] = array(
@ -1788,7 +1784,7 @@
// Limit of search results // Limit of search results
$config['search']['search_limit'] = 100; $config['search']['search_limit'] = 100;
// Boards for searching // Boards for searching
//$config['search']['boards'] = array('a', 'b', 'c', 'd', 'e'); //$config['search']['boards'] = array('a', 'b', 'c', 'd', 'e');
@ -1809,7 +1805,7 @@
// event_handler('post', function($post) { // event_handler('post', function($post) {
// // do something else // // do something else
// //
// // return an error (reject post) // // return an error (reject post)
// return 'Sorry, you cannot post that!'; // return 'Sorry, you cannot post that!';
// }); // });

View File

@ -3001,25 +3001,3 @@ function mod_debug_sql() {
mod_page(_('Debug: SQL'), $config['file_mod_debug_sql'], $args); mod_page(_('Debug: SQL'), $config['file_mod_debug_sql'], $args);
} }
function mod_debug_apc() {
global $config;
if (!hasPermission($config['mod']['debug_apc']))
error($config['error']['noaccess']);
if ($config['cache']['enabled'] != 'apc')
error('APC is not enabled.');
$cache_info = apc_cache_info('user');
// $cached_vars = new APCIterator('user', '/^' . $config['cache']['prefix'] . '/');
$cached_vars = array();
foreach ($cache_info['cache_list'] as $var) {
if ($config['cache']['prefix'] != '' && strpos(isset($var['key']) ? $var['key'] : $var['info'], $config['cache']['prefix']) !== 0)
continue;
$cached_vars[] = $var;
}
mod_page(_('Debug: APC'), $config['file_mod_debug_apc'], array('cached_vars' => $cached_vars));
}

View File

@ -1,6 +1,6 @@
<?php <?php
// Installation/upgrade file // Installation/upgrade file
define('VERSION', '5.1.4'); define('VERSION', '5.1.4');
require 'inc/bootstrap.php'; require 'inc/bootstrap.php';
loadConfig(); loadConfig();
@ -59,41 +59,41 @@ $page = array(
$config['minify_html'] = false; $config['minify_html'] = false;
if (file_exists($config['has_installed'])) { if (file_exists($config['has_installed'])) {
// Check the version number // Check the version number
$version = trim(file_get_contents($config['has_installed'])); $version = trim(file_get_contents($config['has_installed']));
if (empty($version)) if (empty($version))
$version = 'v0.9.1'; $version = 'v0.9.1';
function __query($sql) { function __query($sql) {
sql_open(); sql_open();
if (mysql_version() >= 50503) if (mysql_version() >= 50503)
return query($sql); return query($sql);
else else
return query(str_replace('utf8mb4', 'utf8', $sql)); return query(str_replace('utf8mb4', 'utf8', $sql));
} }
$boards = listBoards(); $boards = listBoards();
switch ($version) { switch ($version) {
case 'v0.9': case 'v0.9':
case 'v0.9.1': case 'v0.9.1':
// Upgrade to v0.9.2-dev // Upgrade to v0.9.2-dev
foreach ($boards as &$_board) { foreach ($boards as &$_board) {
// Add `capcode` field after `trip` // Add `capcode` field after `trip`
query(sprintf("ALTER TABLE `posts_%s` ADD `capcode` VARCHAR( 50 ) NULL AFTER `trip`", $_board['uri'])) or error(db_error()); query(sprintf("ALTER TABLE `posts_%s` ADD `capcode` VARCHAR( 50 ) NULL AFTER `trip`", $_board['uri'])) or error(db_error());
// Resize `trip` to 15 characters // Resize `trip` to 15 characters
query(sprintf("ALTER TABLE `posts_%s` CHANGE `trip` `trip` VARCHAR( 15 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL", $_board['uri'])) or error(db_error()); query(sprintf("ALTER TABLE `posts_%s` CHANGE `trip` `trip` VARCHAR( 15 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL", $_board['uri'])) or error(db_error());
} }
case 'v0.9.2-dev': case 'v0.9.2-dev':
// Upgrade to v0.9.2-dev-1 // Upgrade to v0.9.2-dev-1
// New table: `theme_settings` // New table: `theme_settings`
query("CREATE TABLE IF NOT EXISTS `theme_settings` ( `name` varchar(40) NOT NULL, `value` text, UNIQUE KEY `name` (`name`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;") or error(db_error()); query("CREATE TABLE IF NOT EXISTS `theme_settings` ( `name` varchar(40) NOT NULL, `value` text, UNIQUE KEY `name` (`name`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;") or error(db_error());
// New table: `news` // New table: `news`
query("CREATE TABLE IF NOT EXISTS `news` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` text NOT NULL, `time` int(11) NOT NULL, `subject` text NOT NULL, `body` text NOT NULL, UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;") or error(db_error()); query("CREATE TABLE IF NOT EXISTS `news` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` text NOT NULL, `time` int(11) NOT NULL, `subject` text NOT NULL, `body` text NOT NULL, UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;") or error(db_error());
case 'v0.9.2.1-dev': case 'v0.9.2.1-dev':
@ -101,7 +101,7 @@ if (file_exists($config['has_installed'])) {
// Fix broken version number/mistake // Fix broken version number/mistake
$version = 'v0.9.2-dev-1'; $version = 'v0.9.2-dev-1';
// Upgrade to v0.9.2-dev-2 // Upgrade to v0.9.2-dev-2
foreach ($boards as &$_board) { foreach ($boards as &$_board) {
// Increase field sizes // Increase field sizes
query(sprintf("ALTER TABLE `posts_%s` CHANGE `subject` `subject` VARCHAR( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL", $_board['uri'])) or error(db_error()); query(sprintf("ALTER TABLE `posts_%s` CHANGE `subject` `subject` VARCHAR( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL", $_board['uri'])) or error(db_error());
@ -109,7 +109,7 @@ if (file_exists($config['has_installed'])) {
} }
case 'v0.9.2-dev-2': case 'v0.9.2-dev-2':
// Upgrade to v0.9.2-dev-3 (v0.9.2) // Upgrade to v0.9.2-dev-3 (v0.9.2)
foreach ($boards as &$_board) { foreach ($boards as &$_board) {
// Add `custom_fields` field // Add `custom_fields` field
query(sprintf("ALTER TABLE `posts_%s` ADD `embed` TEXT NULL", $_board['uri'])) or error(db_error()); query(sprintf("ALTER TABLE `posts_%s` ADD `embed` TEXT NULL", $_board['uri'])) or error(db_error());
@ -117,7 +117,7 @@ if (file_exists($config['has_installed'])) {
case 'v0.9.2-dev-3': // v0.9.2-dev-3 == v0.9.2 case 'v0.9.2-dev-3': // v0.9.2-dev-3 == v0.9.2
case 'v0.9.2': case 'v0.9.2':
// Upgrade to v0.9.3-dev-1 // Upgrade to v0.9.3-dev-1
// Upgrade `theme_settings` table // Upgrade `theme_settings` table
query("TRUNCATE TABLE `theme_settings`") or error(db_error()); query("TRUNCATE TABLE `theme_settings`") or error(db_error());
query("ALTER TABLE `theme_settings` ADD `theme` VARCHAR( 40 ) NOT NULL FIRST") or error(db_error()); query("ALTER TABLE `theme_settings` ADD `theme` VARCHAR( 40 ) NOT NULL FIRST") or error(db_error());
@ -149,7 +149,7 @@ if (file_exists($config['has_installed'])) {
foreach ($boards as &$board) { foreach ($boards as &$board) {
$tables[] = "posts_{$board['uri']}"; $tables[] = "posts_{$board['uri']}";
} }
foreach ($tables as &$table) { foreach ($tables as &$table) {
query("ALTER TABLE `{$table}` ENGINE = INNODB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci") or error(db_error()); query("ALTER TABLE `{$table}` ENGINE = INNODB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci") or error(db_error());
} }
@ -173,10 +173,10 @@ if (file_exists($config['has_installed'])) {
query("ALTER TABLE `boards` DROP PRIMARY KEY") or error(db_error()); query("ALTER TABLE `boards` DROP PRIMARY KEY") or error(db_error());
query("ALTER TABLE `reports` DROP INDEX `id`") or error(db_error()); query("ALTER TABLE `reports` DROP INDEX `id`") or error(db_error());
query("ALTER TABLE `boards` DROP INDEX `uri`") or error(db_error()); query("ALTER TABLE `boards` DROP INDEX `uri`") or error(db_error());
query("ALTER IGNORE TABLE `robot` ADD PRIMARY KEY (`hash`)") or error(db_error()); query("ALTER IGNORE TABLE `robot` ADD PRIMARY KEY (`hash`)") or error(db_error());
query("ALTER TABLE `bans` ADD FULLTEXT (`ip`)") or error(db_error()); query("ALTER TABLE `bans` ADD FULLTEXT (`ip`)") or error(db_error());
query("ALTER TABLE `ip_notes` ADD INDEX (`ip`)") or error(db_error()); query("ALTER TABLE `ip_notes` ADD INDEX (`ip`)") or error(db_error());
query("ALTER TABLE `modlogs` ADD INDEX (`time`)") or error(db_error()); query("ALTER TABLE `modlogs` ADD INDEX (`time`)") or error(db_error());
query("ALTER TABLE `boards` ADD PRIMARY KEY(`uri`)") or error(db_error()); query("ALTER TABLE `boards` ADD PRIMARY KEY(`uri`)") or error(db_error());
query("ALTER TABLE `mutes` ADD INDEX (`ip`)") or error(db_error()); query("ALTER TABLE `mutes` ADD INDEX (`ip`)") or error(db_error());
@ -194,9 +194,9 @@ if (file_exists($config['has_installed'])) {
<p style="text-align:center"> <p style="text-align:center">
<a href="?confirm=1">I have read and understood the agreement. Proceed to upgrading.</a> <a href="?confirm=1">I have read and understood the agreement. Proceed to upgrading.</a>
</p>'; </p>';
file_write($config['has_installed'], 'v0.9.4-dev-2'); file_write($config['has_installed'], 'v0.9.4-dev-2');
break; break;
} }
case 'v0.9.4-dev-3': case 'v0.9.4-dev-3':
@ -214,14 +214,14 @@ if (file_exists($config['has_installed'])) {
} }
query("CREATE TABLE IF NOT EXISTS `cites` ( `board` varchar(8) NOT NULL, `post` int(11) NOT NULL, `target_board` varchar(8) NOT NULL, `target` int(11) NOT NULL, KEY `target` (`target_board`,`target`), KEY `post` (`board`,`post`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;") or error(db_error()); query("CREATE TABLE IF NOT EXISTS `cites` ( `board` varchar(8) NOT NULL, `post` int(11) NOT NULL, `target_board` varchar(8) NOT NULL, `target` int(11) NOT NULL, KEY `target` (`target_board`,`target`), KEY `post` (`board`,`post`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;") or error(db_error());
case 'v0.9.5-dev-2': case 'v0.9.5-dev-2':
query("ALTER TABLE `boards` query("ALTER TABLE `boards`
CHANGE `uri` `uri` VARCHAR( 15 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, CHANGE `uri` `uri` VARCHAR( 15 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
CHANGE `title` `title` VARCHAR( 40 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, CHANGE `title` `title` VARCHAR( 40 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
CHANGE `subtitle` `subtitle` VARCHAR( 120 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL") or error(db_error()); CHANGE `subtitle` `subtitle` VARCHAR( 120 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL") or error(db_error());
case 'v0.9.5-dev-3': case 'v0.9.5-dev-3':
// v0.9.5 // v0.9.5
case 'v0.9.5': case 'v0.9.5':
query("ALTER TABLE `boards` query("ALTER TABLE `boards`
CHANGE `uri` `uri` VARCHAR( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, CHANGE `uri` `uri` VARCHAR( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
CHANGE `title` `title` TINYTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, CHANGE `title` `title` TINYTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
CHANGE `subtitle` `subtitle` TINYTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL") or error(db_error()); CHANGE `subtitle` `subtitle` TINYTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL") or error(db_error());
@ -248,12 +248,12 @@ if (file_exists($config['has_installed'])) {
$query->bindValue(':newboard', $board['uri']); $query->bindValue(':newboard', $board['uri']);
$query->bindValue(':oldboard', $board['id']); $query->bindValue(':oldboard', $board['id']);
$query->execute() or error(db_error($query)); $query->execute() or error(db_error($query));
$query = prepare("UPDATE `modlogs` SET `board` = :newboard WHERE `board` = :oldboard"); $query = prepare("UPDATE `modlogs` SET `board` = :newboard WHERE `board` = :oldboard");
$query->bindValue(':newboard', $board['uri']); $query->bindValue(':newboard', $board['uri']);
$query->bindValue(':oldboard', $board['id']); $query->bindValue(':oldboard', $board['id']);
$query->execute() or error(db_error($query)); $query->execute() or error(db_error($query));
$query = prepare("UPDATE `reports` SET `board` = :newboard WHERE `board` = :oldboard"); $query = prepare("UPDATE `reports` SET `board` = :newboard WHERE `board` = :oldboard");
$query->bindValue(':newboard', $board['uri']); $query->bindValue(':newboard', $board['uri']);
$query->bindValue(':oldboard', $board['id']); $query->bindValue(':oldboard', $board['id']);
@ -291,10 +291,10 @@ if (file_exists($config['has_installed'])) {
if (strlen($user['password']) == 40) { if (strlen($user['password']) == 40) {
mt_srand(microtime(true) * 100000 + memory_get_usage(true)); mt_srand(microtime(true) * 100000 + memory_get_usage(true));
$salt = md5(uniqid(mt_rand(), true)); $salt = md5(uniqid(mt_rand(), true));
$user['salt'] = $salt; $user['salt'] = $salt;
$user['password'] = hash('sha256', $user['salt'] . $user['password']); $user['password'] = hash('sha256', $user['salt'] . $user['password']);
$_query = prepare("UPDATE `mods` SET `password` = :password, `salt` = :salt WHERE `id` = :id"); $_query = prepare("UPDATE `mods` SET `password` = :password, `salt` = :salt WHERE `id` = :id");
$_query->bindValue(':id', $user['id']); $_query->bindValue(':id', $user['id']);
$_query->bindValue(':password', $user['password']); $_query->bindValue(':password', $user['password']);
@ -326,7 +326,7 @@ if (file_exists($config['has_installed'])) {
CHANGE `embed` `embed` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, CHANGE `embed` `embed` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;", $board['uri'])) or error(db_error()); DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;", $board['uri'])) or error(db_error());
} }
__query("ALTER TABLE `antispam` __query("ALTER TABLE `antispam`
CHANGE `board` `board` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL , CHANGE `board` `board` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL ,
CHANGE `hash` `hash` CHAR( 40 ) CHARACTER SET ASCII COLLATE ascii_bin NOT NULL , CHANGE `hash` `hash` CHAR( 40 ) CHARACTER SET ASCII COLLATE ascii_bin NOT NULL ,
@ -486,44 +486,44 @@ if (file_exists($config['has_installed'])) {
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1") or error(db_error()); ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1") or error(db_error());
$listquery = query("SELECT * FROM ``bans`` ORDER BY `id`") or error(db_error()); $listquery = query("SELECT * FROM ``bans`` ORDER BY `id`") or error(db_error());
while ($ban = $listquery->fetch(PDO::FETCH_ASSOC)) { while ($ban = $listquery->fetch(PDO::FETCH_ASSOC)) {
$query = prepare("INSERT INTO ``bans_new_temp`` VALUES $query = prepare("INSERT INTO ``bans_new_temp`` VALUES
(NULL, :ipstart, :ipend, :created, :expires, :board, :creator, :reason, :seen, NULL)"); (NULL, :ipstart, :ipend, :created, :expires, :board, :creator, :reason, :seen, NULL)");
$range = Bans::parse_range($ban['ip']); $range = Bans::parse_range($ban['ip']);
if ($range === false) { if ($range === false) {
// Invalid retard ban; just skip it. // Invalid retard ban; just skip it.
continue; continue;
} }
$query->bindValue(':ipstart', $range[0]); $query->bindValue(':ipstart', $range[0]);
if ($range[1] !== false && $range[1] != $range[0]) if ($range[1] !== false && $range[1] != $range[0])
$query->bindValue(':ipend', $range[1]); $query->bindValue(':ipend', $range[1]);
else else
$query->bindValue(':ipend', null, PDO::PARAM_NULL); $query->bindValue(':ipend', null, PDO::PARAM_NULL);
$query->bindValue(':created', $ban['set']); $query->bindValue(':created', $ban['set']);
if ($ban['expires']) if ($ban['expires'])
$query->bindValue(':expires', $ban['expires']); $query->bindValue(':expires', $ban['expires']);
else else
$query->bindValue(':expires', null, PDO::PARAM_NULL); $query->bindValue(':expires', null, PDO::PARAM_NULL);
if ($ban['board']) if ($ban['board'])
$query->bindValue(':board', $ban['board']); $query->bindValue(':board', $ban['board']);
else else
$query->bindValue(':board', null, PDO::PARAM_NULL); $query->bindValue(':board', null, PDO::PARAM_NULL);
$query->bindValue(':creator', $ban['mod']); $query->bindValue(':creator', $ban['mod']);
if ($ban['reason']) if ($ban['reason'])
$query->bindValue(':reason', $ban['reason']); $query->bindValue(':reason', $ban['reason']);
else else
$query->bindValue(':reason', null, PDO::PARAM_NULL); $query->bindValue(':reason', null, PDO::PARAM_NULL);
$query->bindValue(':seen', $ban['seen']); $query->bindValue(':seen', $ban['seen']);
$query->execute() or error(db_error($query)); $query->execute() or error(db_error($query));
} }
// Drop old bans table // Drop old bans table
query("DROP TABLE ``bans``") or error(db_error()); query("DROP TABLE ``bans``") or error(db_error());
// Replace with new table // Replace with new table
@ -555,9 +555,9 @@ if (file_exists($config['has_installed'])) {
<p style="text-align:center"> <p style="text-align:center">
<a href="?confirm2=1">I have read and understood the agreement. Proceed to upgrading.</a> <a href="?confirm2=1">I have read and understood the agreement. Proceed to upgrading.</a>
</p>'; </p>';
file_write($config['has_installed'], '4.4.97'); file_write($config['has_installed'], '4.4.97');
break; break;
} }
case '4.4.98-pre': case '4.4.98-pre':
@ -573,9 +573,9 @@ if (file_exists($config['has_installed'])) {
<p style="text-align:center"> <p style="text-align:center">
<a href="?confirm3=1">I have read and understood the warning. Proceed to upgrading.</a> <a href="?confirm3=1">I have read and understood the warning. Proceed to upgrading.</a>
</p>'; </p>';
file_write($config['has_installed'], '4.5.2'); file_write($config['has_installed'], '4.5.2');
break; break;
} }
@ -641,7 +641,7 @@ if (file_exists($config['has_installed'])) {
// Update version number // Update version number
file_write($config['has_installed'], VERSION); file_write($config['has_installed'], VERSION);
$page['title'] = 'Upgraded'; $page['title'] = 'Upgraded';
$page['body'] = '<p style="text-align:center">Successfully upgraded from ' . $version . ' to <strong>' . VERSION . '</strong>.</p>'; $page['body'] = '<p style="text-align:center">Successfully upgraded from ' . $version . ' to <strong>' . VERSION . '</strong>.</p>';
break; break;
@ -653,8 +653,8 @@ if (file_exists($config['has_installed'])) {
$page['title'] = 'Already installed'; $page['title'] = 'Already installed';
$page['body'] = '<p style="text-align:center">It appears that vichan is already installed (' . $version . ') and there is nothing to upgrade! Delete <strong>' . $config['has_installed'] . '</strong> to reinstall.</p>'; $page['body'] = '<p style="text-align:center">It appears that vichan is already installed (' . $version . ') and there is nothing to upgrade! Delete <strong>' . $config['has_installed'] . '</strong> to reinstall.</p>';
break; break;
} }
die(Element('page.html', $page)); die(Element('page.html', $page));
} }
@ -686,11 +686,11 @@ if ($step == 0) {
<p style="text-align:center"> <p style="text-align:center">
<a href="?step=1">I have read and understood the agreement. Proceed to installation.</a> <a href="?step=1">I have read and understood the agreement. Proceed to installation.</a>
</p>'; </p>';
echo Element('page.html', $page); echo Element('page.html', $page);
} elseif ($step == 1) { } elseif ($step == 1) {
$page['title'] = 'Pre-installation test'; $page['title'] = 'Pre-installation test';
$can_exec = true; $can_exec = true;
if (!function_exists('shell_exec')) if (!function_exists('shell_exec'))
$can_exec = false; $can_exec = false;
@ -700,12 +700,12 @@ if ($step == 0) {
$can_exec = false; $can_exec = false;
elseif (trim(shell_exec('echo "TEST"')) !== 'TEST') elseif (trim(shell_exec('echo "TEST"')) !== 'TEST')
$can_exec = false; $can_exec = false;
if (!defined('PHP_VERSION_ID')) { if (!defined('PHP_VERSION_ID')) {
$version = explode('.', PHP_VERSION); $version = explode('.', PHP_VERSION);
define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
} }
// Required extensions // Required extensions
$extensions = array( $extensions = array(
'PDO' => array( 'PDO' => array(
@ -876,12 +876,10 @@ if ($step == 0) {
), ),
array( array(
'category' => 'Misc', 'category' => 'Misc',
'name' => 'Caching available (APC(u), XCache, Memcached or Redis)', 'name' => 'Caching available (APCu, Memcached or Redis)',
'result' => extension_loaded('apcu') || extension_loaded('apc') || 'result' => extension_loaded('apcu') || extension_loaded('memcached') || extension_loaded('redis'),
extension_loaded('xcache') || extension_loaded('memcached') ||
extension_loaded('redis'),
'required' => false, 'required' => false,
'message' => 'You will not be able to enable the additional caching system, designed to minimize SQL queries and significantly improve performance. <a href="http://php.net/manual/en/book.apc.php">APC</a> is the recommended method of caching, but <a href="http://xcache.lighttpd.net/">XCache</a>, <a href="http://www.php.net/manual/en/intro.memcached.php">Memcached</a> and <a href="http://pecl.php.net/package/redis">Redis</a> are also supported.' 'message' => 'You will not be able to enable the additional caching system, designed to minimize SQL queries and significantly improve performance. <a href="https://www.php.net/manual/en/book.apcu.php">APCu</a> is the recommended method of caching, but <a href="http://www.php.net/manual/en/intro.memcached.php">Memcached</a> and <a href="http://pecl.php.net/package/redis">Redis</a> are also supported.'
), ),
array( array(
'category' => 'Misc', 'category' => 'Misc',
@ -893,7 +891,7 @@ if ($step == 0) {
); );
$config['font_awesome'] = true; $config['font_awesome'] = true;
$additional_config = array(); $additional_config = array();
foreach ($tests as $test) { foreach ($tests as $test) {
if ($test['result'] && isset($test['effect'])) { if ($test['result'] && isset($test['effect'])) {
@ -921,7 +919,7 @@ if ($step == 0) {
$sg = new SaltGen(); $sg = new SaltGen();
$config['cookies']['salt'] = $sg->generate(); $config['cookies']['salt'] = $sg->generate();
$config['secure_trip_salt'] = $sg->generate(); $config['secure_trip_salt'] = $sg->generate();
echo Element('page.html', array( echo Element('page.html', array(
'body' => Element('installer/config.html', array( 'body' => Element('installer/config.html', array(
'config' => $config, 'config' => $config,
@ -934,7 +932,7 @@ if ($step == 0) {
$more = $_POST['more']; $more = $_POST['more'];
unset($_POST['more']); unset($_POST['more']);
$instance_config = $instance_config =
'<'.'?php '<'.'?php
/* /*
@ -946,13 +944,13 @@ if ($step == 0) {
*/ */
'; ';
create_config_from_array($instance_config, $_POST); create_config_from_array($instance_config, $_POST);
$instance_config .= "\n"; $instance_config .= "\n";
$instance_config .= $more; $instance_config .= $more;
$instance_config .= "\n"; $instance_config .= "\n";
if (@file_put_contents('inc/secrets.php', $instance_config)) { if (@file_put_contents('inc/secrets.php', $instance_config)) {
// flushes opcache if php >= 5.5.0 or opcache is installed via PECL // flushes opcache if php >= 5.5.0 or opcache is installed via PECL
if (function_exists('opcache_invalidate')) { if (function_exists('opcache_invalidate')) {
@ -973,22 +971,22 @@ if ($step == 0) {
} }
} elseif ($step == 4) { } elseif ($step == 4) {
// SQL installation // SQL installation
buildJavascript(); buildJavascript();
$sql = @file_get_contents('install.sql') or error("Couldn't load install.sql."); $sql = @file_get_contents('install.sql') or error("Couldn't load install.sql.");
sql_open(); sql_open();
$mysql_version = mysql_version(); $mysql_version = mysql_version();
// This code is probably horrible, but what I'm trying // This code is probably horrible, but what I'm trying
// to do is find all of the SQL queires and put them // to do is find all of the SQL queires and put them
// in an array. // in an array.
preg_match_all("/(^|\n)((SET|CREATE|INSERT).+)\n\n/msU", $sql, $queries); preg_match_all("/(^|\n)((SET|CREATE|INSERT).+)\n\n/msU", $sql, $queries);
$queries = $queries[2]; $queries = $queries[2];
$queries[] = Element('posts.sql', array('board' => 'b')); $queries[] = Element('posts.sql', array('board' => 'b'));
$sql_errors = ''; $sql_errors = '';
foreach ($queries as $query) { foreach ($queries as $query) {
if ($mysql_version < 50503) if ($mysql_version < 50503)
@ -997,10 +995,10 @@ if ($step == 0) {
if (!query($query)) if (!query($query))
$sql_errors .= '<li>' . db_error() . '</li>'; $sql_errors .= '<li>' . db_error() . '</li>';
} }
$page['title'] = 'Installation complete'; $page['title'] = 'Installation complete';
$page['body'] = '<p style="text-align:center">Thank you for using vichan. Please remember to report any bugs you discover. <a href="https://github.com/vichan-devel/vichan/wiki/Configuration-Basics">How do I edit the config files?</a></p>'; $page['body'] = '<p style="text-align:center">Thank you for using vichan. Please remember to report any bugs you discover. <a href="https://github.com/vichan-devel/vichan/wiki/Configuration-Basics">How do I edit the config files?</a></p>';
if (!empty($sql_errors)) { if (!empty($sql_errors)) {
$page['body'] .= '<div class="ban"><h2>SQL errors</h2><p>SQL errors were encountered when trying to install the database. This may be the result of using a database which is already occupied with a vichan installation; if so, you can probably ignore this.</p><p>The errors encountered were:</p><ul>' . $sql_errors . '</ul><p><a href="?step=5">Ignore errors and complete installation.</a></p></div>'; $page['body'] .= '<div class="ban"><h2>SQL errors</h2><p>SQL errors were encountered when trying to install the database. This may be the result of using a database which is already occupied with a vichan installation; if so, you can probably ignore this.</p><p>The errors encountered were:</p><ul>' . $sql_errors . '</ul><p><a href="?step=5">Ignore errors and complete installation.</a></p></div>';
} else { } else {
@ -1009,29 +1007,29 @@ if ($step == 0) {
setupBoard($_board); setupBoard($_board);
buildIndex(); buildIndex();
} }
file_write($config['has_installed'], VERSION); file_write($config['has_installed'], VERSION);
/*if (!file_unlink(__FILE__)) { /*if (!file_unlink(__FILE__)) {
$page['body'] .= '<div class="ban"><h2>Delete install.php!</h2><p>I couldn\'t remove <strong>install.php</strong>. You will have to remove it manually.</p></div>'; $page['body'] .= '<div class="ban"><h2>Delete install.php!</h2><p>I couldn\'t remove <strong>install.php</strong>. You will have to remove it manually.</p></div>';
}*/ }*/
} }
echo Element('page.html', $page); echo Element('page.html', $page);
} elseif ($step == 5) { } elseif ($step == 5) {
$page['title'] = 'Installation complete'; $page['title'] = 'Installation complete';
$page['body'] = '<p style="text-align:center">Thank you for using vichan. Please remember to report any bugs you discover.</p>'; $page['body'] = '<p style="text-align:center">Thank you for using vichan. Please remember to report any bugs you discover.</p>';
$boards = listBoards(); $boards = listBoards();
foreach ($boards as &$_board) { foreach ($boards as &$_board) {
setupBoard($_board); setupBoard($_board);
buildIndex(); buildIndex();
} }
file_write($config['has_installed'], VERSION); file_write($config['has_installed'], VERSION);
if (!file_unlink(__FILE__)) { if (!file_unlink(__FILE__)) {
$page['body'] .= '<div class="ban"><h2>Delete install.php!</h2><p>I couldn\'t remove <strong>install.php</strong>. You will have to remove it manually.</p></div>'; $page['body'] .= '<div class="ban"><h2>Delete install.php!</h2><p>I couldn\'t remove <strong>install.php</strong>. You will have to remove it manually.</p></div>';
} }
echo Element('page.html', $page); echo Element('page.html', $page);
} }

37
mod.php
View File

@ -20,16 +20,16 @@ $pages = array(
'/' => 'dashboard', // dashboard '/' => 'dashboard', // dashboard
'/confirm/(.+)' => 'confirm', // confirm action (if javascript didn't work) '/confirm/(.+)' => 'confirm', // confirm action (if javascript didn't work)
'/logout' => 'secure logout', // logout '/logout' => 'secure logout', // logout
'/users' => 'users', // manage users '/users' => 'users', // manage users
'/users/(\d+)/(promote|demote)' => 'secure user_promote', // prmote/demote user '/users/(\d+)/(promote|demote)' => 'secure user_promote', // prmote/demote user
'/users/(\d+)' => 'secure_POST user', // edit user '/users/(\d+)' => 'secure_POST user', // edit user
'/users/new' => 'secure_POST user_new', // create a new user '/users/new' => 'secure_POST user_new', // create a new user
'/new_PM/([^/]+)' => 'secure_POST new_pm', // create a new pm '/new_PM/([^/]+)' => 'secure_POST new_pm', // create a new pm
'/PM/(\d+)(/reply)?' => 'pm', // read a pm '/PM/(\d+)(/reply)?' => 'pm', // read a pm
'/inbox' => 'inbox', // pm inbox '/inbox' => 'inbox', // pm inbox
'/log' => 'log', // modlog '/log' => 'log', // modlog
'/log/(\d+)' => 'log', // modlog '/log/(\d+)' => 'log', // modlog
'/log:([^/:]+)' => 'user_log', // modlog '/log:([^/:]+)' => 'user_log', // modlog
@ -45,18 +45,18 @@ $pages = array(
'/edit_page/(\d+)' => 'secure_POST edit_page', '/edit_page/(\d+)' => 'secure_POST edit_page',
'/edit_pages/delete/([a-z0-9]+)' => 'secure delete_page', '/edit_pages/delete/([a-z0-9]+)' => 'secure delete_page',
'/edit_pages/delete/([a-z0-9]+)/(\%b)' => 'secure delete_page_board', '/edit_pages/delete/([a-z0-9]+)/(\%b)' => 'secure delete_page_board',
'/noticeboard' => 'secure_POST noticeboard', // view noticeboard '/noticeboard' => 'secure_POST noticeboard', // view noticeboard
'/noticeboard/(\d+)' => 'secure_POST noticeboard', // view noticeboard '/noticeboard/(\d+)' => 'secure_POST noticeboard', // view noticeboard
'/noticeboard/delete/(\d+)' => 'secure noticeboard_delete', // delete from noticeboard '/noticeboard/delete/(\d+)' => 'secure noticeboard_delete', // delete from noticeboard
'/edit/(\%b)' => 'secure_POST edit_board', // edit board details '/edit/(\%b)' => 'secure_POST edit_board', // edit board details
'/new-board' => 'secure_POST new_board', // create a new board '/new-board' => 'secure_POST new_board', // create a new board
'/rebuild' => 'secure_POST rebuild', // rebuild static files '/rebuild' => 'secure_POST rebuild', // rebuild static files
'/reports' => 'reports', // report queue '/reports' => 'reports', // report queue
'/reports/(\d+)/dismiss(&all|&post)?' => 'secure report_dismiss', // dismiss a report '/reports/(\d+)/dismiss(&all|&post)?' => 'secure report_dismiss', // dismiss a report
'/IP/([\w.:]+)' => 'secure_POST ip', // view ip address '/IP/([\w.:]+)' => 'secure_POST ip', // view ip address
'/IP/([\w.:]+)/remove_note/(\d+)' => 'secure ip_remove_note', // remove note from ip address '/IP/([\w.:]+)/remove_note/(\d+)' => 'secure ip_remove_note', // remove note from ip address
@ -65,7 +65,7 @@ $pages = array(
'/bans.json' => 'secure bans_json', // ban list JSON '/bans.json' => 'secure bans_json', // ban list JSON
'/edit_ban/(\d+)' => 'secure_POST edit_ban', '/edit_ban/(\d+)' => 'secure_POST edit_ban',
'/ban-appeals' => 'secure_POST ban_appeals', // view ban appeals '/ban-appeals' => 'secure_POST ban_appeals', // view ban appeals
'/recent/(\d+)' => 'recent_posts', // view recent posts '/recent/(\d+)' => 'recent_posts', // view recent posts
'/search' => 'search_redirect', // search '/search' => 'search_redirect', // search
@ -84,21 +84,20 @@ $pages = array(
'/(\%b)/(un)?sticky/(\d+)' => 'secure sticky', // sticky thread '/(\%b)/(un)?sticky/(\d+)' => 'secure sticky', // sticky thread
'/(\%b)/(un)?cycle/(\d+)' => 'secure cycle', // cycle thread '/(\%b)/(un)?cycle/(\d+)' => 'secure cycle', // cycle thread
'/(\%b)/bump(un)?lock/(\d+)' => 'secure bumplock', // "bumplock" thread '/(\%b)/bump(un)?lock/(\d+)' => 'secure bumplock', // "bumplock" thread
'/themes' => 'themes_list', // manage themes '/themes' => 'themes_list', // manage themes
'/themes/(\w+)' => 'secure_POST theme_configure', // configure/reconfigure theme '/themes/(\w+)' => 'secure_POST theme_configure', // configure/reconfigure theme
'/themes/(\w+)/rebuild' => 'secure theme_rebuild', // rebuild theme '/themes/(\w+)/rebuild' => 'secure theme_rebuild', // rebuild theme
'/themes/(\w+)/uninstall' => 'secure theme_uninstall', // uninstall theme '/themes/(\w+)/uninstall' => 'secure theme_uninstall', // uninstall theme
'/config' => 'secure_POST config', // config editor '/config' => 'secure_POST config', // config editor
'/config/(\%b)' => 'secure_POST config', // config editor '/config/(\%b)' => 'secure_POST config', // config editor
// these pages aren't listed in the dashboard without $config['debug'] // these pages aren't listed in the dashboard without $config['debug']
//'/debug/antispam' => 'debug_antispam', //'/debug/antispam' => 'debug_antispam',
//'/debug/recent' => 'debug_recent_posts', //'/debug/recent' => 'debug_recent_posts',
//'/debug/apc' => 'debug_apc',
//'/debug/sql' => 'secure_POST debug_sql', //'/debug/sql' => 'secure_POST debug_sql',
// This should always be at the end: // This should always be at the end:
'/(\%b)/' => 'view_board', '/(\%b)/' => 'view_board',
'/(\%b)/' . preg_quote($config['file_index'], '!') => 'view_board', '/(\%b)/' . preg_quote($config['file_index'], '!') => 'view_board',
@ -139,7 +138,7 @@ $pages = $new_pages;
foreach ($pages as $uri => $handler) { foreach ($pages as $uri => $handler) {
if (preg_match($uri, $query, $matches)) { if (preg_match($uri, $query, $matches)) {
$matches = array_slice($matches, 1); $matches = array_slice($matches, 1);
if (isset($matches['board'])) { if (isset($matches['board'])) {
$board_match = $matches['board']; $board_match = $matches['board'];
unset($matches['board']); unset($matches['board']);
@ -148,12 +147,12 @@ foreach ($pages as $uri => $handler) {
$matches[$key] = $board_match[1]; $matches[$key] = $board_match[1];
} }
} }
if (is_string($handler) && preg_match('/^secure(_POST)? /', $handler, $m)) { if (is_string($handler) && preg_match('/^secure(_POST)? /', $handler, $m)) {
$secure_post_only = isset($m[1]); $secure_post_only = isset($m[1]);
if (!$secure_post_only || $_SERVER['REQUEST_METHOD'] == 'POST') { if (!$secure_post_only || $_SERVER['REQUEST_METHOD'] == 'POST') {
$token = isset($matches['token']) ? $matches['token'] : (isset($_POST['token']) ? $_POST['token'] : false); $token = isset($matches['token']) ? $matches['token'] : (isset($_POST['token']) ? $_POST['token'] : false);
if ($token === false) { if ($token === false) {
if ($secure_post_only) if ($secure_post_only)
error($config['error']['csrf']); error($config['error']['csrf']);
@ -162,7 +161,7 @@ foreach ($pages as $uri => $handler) {
exit; exit;
} }
} }
// CSRF-protected page; validate security token // CSRF-protected page; validate security token
$actual_query = preg_replace('!/([a-f0-9]{8})$!', '', $query); $actual_query = preg_replace('!/([a-f0-9]{8})$!', '', $query);
if ($token != make_secure_link_token(substr($actual_query, 1))) { if ($token != make_secure_link_token(substr($actual_query, 1))) {
@ -171,7 +170,7 @@ foreach ($pages as $uri => $handler) {
} }
$handler = preg_replace('/^secure(_POST)? /', '', $handler); $handler = preg_replace('/^secure(_POST)? /', '', $handler);
} }
if ($config['debug']) { if ($config['debug']) {
$debug['mod_page'] = array( $debug['mod_page'] = array(
'req' => $query, 'req' => $query,
@ -201,7 +200,7 @@ foreach ($pages as $uri => $handler) {
} else { } else {
error("Mod page '$handler' not a string, and not callable!"); error("Mod page '$handler' not a string, and not callable!");
} }
exit; exit;
} }
} }