diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 00000000..1b82198d
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,4 @@
+**/.git
+**/.gitignore
+/local-www
+**/.gitkeep
diff --git a/.gitignore b/.gitignore
index 6cade620..5571b91b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,6 +55,7 @@ php_errors.log
#vichan custom
favicon.ico
/static/spoiler.png
+local-www
piwik/
jwplayer/
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..4e76f72e
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,29 @@
+FROM php:8.1.8-fpm
+
+COPY . /code
+
+RUN docker-php-ext-install pdo pdo_mysql
+RUN apt-get update -y && apt-get install -y libpng-dev libjpeg-dev libonig-dev
+RUN docker-php-ext-install mbstring
+RUN apt-get update -y && apt-get install -y libmcrypt-dev
+# RUN docker-php-ext-install -j$(nproc) mcrypt
+RUN docker-php-ext-install iconv
+RUN apt-get update -y && apt-get install -y imagemagick
+RUN apt-get update -y && apt-get install -y graphicsmagick
+RUN apt-get update -y && apt-get install -y gifsicle
+# RUN docker-php-ext-configure gd
+# --with-jpeg=/usr/include
+# --with-png-dir=/usr \
+RUN docker-php-ext-install gd
+RUN apt-get update -y \
+ && apt-get install -y libmemcached11 libmemcachedutil2 build-essential libmemcached-dev libz-dev git \
+ && pecl install memcached \
+ && echo extension=memcached.so >> /usr/local/etc/php/conf.d/memcached.ini \
+ && apt-get remove -y build-essential libmemcached-dev libz-dev \
+ && apt-get autoremove -y \
+ && apt-get clean \
+ && rm -rf /tmp/pear \
+ && curl -sS https://getcomposer.org/installer -o composer-setup.php \
+ && php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
+ && docker-php-ext-install bcmath \
+ && cd /code && composer install
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 9ae4f02f..1d391f58 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -5,17 +5,17 @@ services:
context: .
dockerfile: ./docker/nginx/Dockerfile
ports:
- - "8080:80"
+ - "9091:80"
depends_on:
- - db
+ - leftypol-db
volumes:
- - ./:/code
+ - ./local-www:/var/www/html
- ./docker/nginx/leftypol.conf:/etc/nginx/conf.d/default.conf
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./docker/nginx/proxy.conf:/etc/nginx/conf.d/proxy.conf
networks:
- leftchan_net:
- ipv4_address: 172.20.0.3
+ d_leftypol_org:
+ ipv4_address: 172.21.0.3
links:
- php
php:
@@ -23,30 +23,31 @@ services:
context: .
dockerfile: ./docker/php/Dockerfile
volumes:
- - ./:/code
+ - ./local-www:/var/www
- ./docker/php/www.conf:/usr/local/etc/php-fpm.d/www.conf
networks:
- leftchan_net:
- ipv4_address: 172.20.0.4
+ d_leftypol_org:
+ ipv4_address: 172.21.0.4
#MySQL Service
- db:
+ leftypol-db:
image: mysql:8.0.35
- container_name: db
+ container_name: leftypol-db
restart: unless-stopped
tty: true
ports:
- "3306:3306"
environment:
- MYSQL_DATABASE: lainchan
- MYSQL_ROOT_PASSWORD: M9q5lO0RxJVh
+ MYSQL_DATABASE: vichan
+ MYSQL_ROOT_PASSWORD: password
+ command: "--default-authentication-plugin=mysql_native_password"
networks:
- leftchan_net:
- ipv4_address: 172.20.0.2
+ d_leftypol_org:
+ ipv4_address: 172.21.0.2
#Docker Networks
networks:
- leftchan_net:
+ d_leftypol_org:
ipam:
driver: default
config:
- - subnet: 172.20.0.0/16
+ - subnet: 172.21.0.0/16
diff --git a/docker/common-setup.sh b/docker/common-setup.sh
deleted file mode 100755
index bf30bd20..00000000
--- a/docker/common-setup.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-
-set -eu
-
-install -m 775 -o leftypol -g leftypol -d /var/www-leftypol
-ln -s \
- /code/banners/ \
- /code/static/ \
- /code/stylesheets/ \
- /code/tools/ \
- /code/walls/ \
- /code/*.php \
- /code/404.html \
- /code/LICENSE.* \
- /code/robots.txt \
- /code/install.sql \
- /var/www-leftypol/
-
-install -m 775 -o leftypol -g leftypol -d /var/www-leftypol/js
-ln -s /code/js/* /var/www-leftypol/js/
-
-install -m 775 -o leftypol -g leftypol -d /var/www-leftypol/templates
-install -m 775 -o leftypol -g leftypol -d /var/www-leftypol/templates/cache
-ln -s /code/templates/* /var/www-leftypol/templates/
-
-install -m 775 -o leftypol -g leftypol -d /var/www-leftypol/inc
-ln -s /code/inc/* /var/www-leftypol/inc/
diff --git a/docker/doc.md b/docker/doc.md
new file mode 100644
index 00000000..13ad93a6
--- /dev/null
+++ b/docker/doc.md
@@ -0,0 +1,4 @@
+The `php-fpm` process runs containerized.
+The php application always uses `/var/www` as it's work directory and home folder, and if `/var/www` is bind mounted it
+is necessary to adjust the path passed via FastCGI to `php-fpm` by changing the root directory to `/var/www`.
+This can achieved in nginx by setting the `fastcgi_param SCRIPT_FILENAME` to `/var/www/$fastcgi_script_name;`
diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile
index e58381da..d9d4bcc4 100644
--- a/docker/nginx/Dockerfile
+++ b/docker/nginx/Dockerfile
@@ -1,11 +1,8 @@
FROM nginx:1.25.3-alpine
COPY . /code
-RUN addgroup --system leftypol \
- && adduser --system leftypol \
- && adduser leftypol leftypol \
- && /code/docker/common-setup.sh
+RUN adduser --system www-data \
+ && adduser www-data www-data
-
-CMD ["nginx", "-g", "daemon off;"]
-EXPOSE 80 443
\ No newline at end of file
+CMD [ "nginx", "-g", "daemon off;" ]
+EXPOSE 80
diff --git a/docker/nginx/leftypol.conf b/docker/nginx/leftypol.conf
index eada8ee9..cdb28076 100644
--- a/docker/nginx/leftypol.conf
+++ b/docker/nginx/leftypol.conf
@@ -6,7 +6,7 @@ server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name leftypol;
- root /var/www-leftypol;
+ root /var/www/html;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
@@ -15,9 +15,24 @@ server {
charset utf-8;
location ~ ^([^.\?]*[^\/])$ {
- try_files $uri @addslash;
+ try_files $uri @addslash;
}
+ # Expire rules for static content
+ # Media: images, icons, video, audio, HTC
+ location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
+ expires 1M;
+ access_log off;
+ log_not_found off;
+ add_header Cache-Control "public";
+ }
+ # CSS and Javascript
+ location ~* \.(?:css|js)$ {
+ expires 1y;
+ access_log off;
+ log_not_found off;
+ add_header Cache-Control "public";
+ }
# Expire rules for static content
# Media: images, icons, video, audio, HTC
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
@@ -39,7 +54,7 @@ server {
}
location @addslash {
- return 301 $uri/;
+ return 301 $uri/;
}
location / {
@@ -56,7 +71,7 @@ server {
proxy_set_header Forwarded-Request-Id $x_request_id;
fastcgi_pass php-upstream;
fastcgi_index index.php;
- fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
+ fastcgi_param SCRIPT_FILENAME /var/www/$fastcgi_script_name;
fastcgi_read_timeout 600;
include fastcgi_params;
}
diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf
index 8a4ba95f..6ac68e98 100644
--- a/docker/nginx/nginx.conf
+++ b/docker/nginx/nginx.conf
@@ -1,15 +1,17 @@
# This and proxy.conf are based on
# https://github.com/dead-guru/devichan/blob/master/nginx/nginx.conf
-user leftypol;
+user www-data;
worker_processes auto;
# daemon off;
# error_log /var/log/nginx/error.log warn;
error_log /dev/stdout warn;
-pid /var/run/nginx.pid;
+pid /var/run/nginx.pid;
+
events {
worker_connections 1024;
}
+
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
diff --git a/docker/nginx/proxy.conf b/docker/nginx/proxy.conf
index bc22ea34..6830cd5f 100644
--- a/docker/nginx/proxy.conf
+++ b/docker/nginx/proxy.conf
@@ -33,7 +33,7 @@ real_ip_header X-Forwarded-For;
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12;
-set_real_ip_from 172.18.0.0/12;
+set_real_ip_from 172.18.0.0;
set_real_ip_from 192.168.0.0/24;
set_real_ip_from 127.0.0.0/8;
diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile
index cb2225bb..48694790 100644
--- a/docker/php/Dockerfile
+++ b/docker/php/Dockerfile
@@ -1,47 +1,89 @@
# Based on https://github.com/dead-guru/devichan/blob/master/php-fpm/Dockerfile
FROM composer AS composer
-FROM php:8.1-fpm-bullseye
-COPY --from=composer /usr/bin/composer /usr/bin/composer
-COPY . /code
+FROM php:7.2-fpm-alpine
-RUN apt-get update && apt-get upgrade -y && apt-get install -y \
- zlib1g-dev libicu-dev g++ \
- libjpeg62-turbo-dev \
- libzip-dev \
- libpng-dev \
- libwebp-dev \
- libfreetype6-dev \
- libxml2-dev \
- git \
- zip \
- ffmpeg \
- libonig-dev \
- unzip \
- libcurl4-openssl-dev \
- libmagickwand-dev \
- gifsicle \
- graphicsmagick \
- gettext \
- imagemagick \
- locales locales-all \
- libmagickwand-dev \
- libmcrypt-dev \
+RUN apk add --no-cache \
+ zlib \
+ zlib-dev \
+ libpng \
+ libpng-dev \
+ libjpeg-turbo \
+ libjpeg-turbo-dev \
+ libwebp \
+ libwebp-dev \
+ libcurl \
+ curl-dev \
+ imagemagick \
+ graphicsmagick \
+ gifsicle \
+ ffmpeg \
+ bind-tools \
+ gettext \
+ gettext-dev \
+ icu-dev \
+ oniguruma \
+ oniguruma-dev \
+ libmcrypt \
+ libmcrypt-dev \
+ lz4-libs \
+ lz4-dev \
+ imagemagick-dev \
+ pcre-dev \
+ $PHPIZE_DEPS \
&& docker-php-ext-configure gd \
- --with-webp=/usr/include/webp \
- --with-jpeg=/usr/include \
- --with-freetype=/usr/include/freetype2/ \
+ --with-webp-dir=/usr/include/webp \
+ --with-jpeg-dir=/usr/include \
+ && docker-php-ext-install -j$(nproc) \
+ gd \
+ curl \
+ bcmath \
+ opcache \
+ pdo_mysql \
+ gettext \
+ intl \
+ mbstring \
+ && pecl update-channels \
+ && pecl install -o -f igbinary \
&& pecl install redis \
&& pecl install imagick \
- && pecl install -o -f igbinary \
- && docker-php-ext-install gd zip opcache intl pdo pdo_mysql mysqli bcmath gettext iconv mbstring curl \
- && docker-php-ext-enable igbinary redis imagick \
- && useradd -MU leftypol \
- && /code/docker/common-setup.sh \
- && ln -s /code/composer.json /code/composer.lock /var/www-leftypol/ \
- && cd /var/www-leftypol && composer install
+ $$ docker-php-ext-enable \
+ igbinary \
+ redis \
+ imagick \
+ && apk del \
+ zlib-dev \
+ libpng-dev \
+ libjpeg-turbo-dev \
+ libwebp-dev \
+ curl-dev \
+ gettext-dev \
+ oniguruma-dev \
+ libmcrypt-dev \
+ lz4-dev \
+ imagemagick-dev \
+ pcre-dev \
+ $PHPIZE_DEPS \
+ && rm -rf /var/cache/*
+RUN rmdir /var/www/html \
+ && install -d -m 744 -o www-data -g www-data /var/www \
+ && install -d -m 700 -o www-data -g www-data /var/tmp/vichan \
+ && install -d -m 700 -o www-data -g www-data /var/cache/gen-cache \
+ && install -d -m 700 -o www-data -g www-data /var/cache/template-cache
-# RUN /code/docker/common-setup.sh php
-WORKDIR "/var/www-leftypol"
-CMD ["php-fpm"]
-EXPOSE 9000
\ No newline at end of file
+COPY --from=composer /usr/bin/composer /usr/local/bin/composer
+
+# Copy the bootstrap script.
+COPY ./docker/php/bootstrap.sh /usr/local/bin/bootstrap.sh
+
+# Copy the actual project (use .dockerignore to exclude stuff).
+COPY . /code
+
+# Make the instance configuration owned by www-data.
+# Make it writable by php.
+# Install the compose depedencies.
+RUN cd /code && composer install
+
+WORKDIR "/var/www"
+CMD [ "bootstrap.sh" ]
+EXPOSE 9000
diff --git a/docker/php/bootstrap.sh b/docker/php/bootstrap.sh
new file mode 100755
index 00000000..e94dcf28
--- /dev/null
+++ b/docker/php/bootstrap.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+set -eu
+
+function set_cfg() {
+ if [ ! -f "/var/www/inc/$1" ]; then
+ echo "INFO: Resetting $1"
+ touch "/var/www/inc/$1"
+ chown www-data "/var/www/inc/$1"
+ chgrp www-data "/var/www/inc/$1"
+ chmod 600 "/var/www/inc/$1"
+ else
+ echo "INFO: Using existing $1"
+ fi
+}
+
+if ! mountpoint -q /var/www; then
+ echo "WARNING: '/var/www' is not a mountpoint. All the data will remain inside the container!"
+fi
+
+if [ ! -w /var/www ] ; then
+ echo "ERROR: '/var/www' is not writable. Closing."
+ exit 1
+fi
+
+# Link the entrypoints from the exposed directory.
+ln -nfs \
+ /code/banners/ \
+ /code/tools/ \
+ /code/walls/ \
+ /code/*.php \
+ /code/LICENSE.* \
+ /code/404.html \
+ /code/install.sql \
+ /var/www/
+# Static files accessible from the webserver must be copied.
+cp -ur /code/static /var/www/
+cp -ur /code/stylesheets /var/www/
+
+# Ensure correct permissions are set, since this might be bind mount.
+chown www-data /var/www
+chgrp www-data /var/www
+
+# Initialize an empty robots.txt with the default if it doesn't exist.
+touch /var/www/robots.txt
+
+# Link the cache and tmp files directory.
+ln -nfs /var/tmp/vichan /var/www/tmp
+
+# Link the javascript directory.
+ln -nfs /code/js /var/www/
+
+# Link the html templates directory and it's cache.
+ln -nfs /code/templates /var/www/
+ln -nfs -T /var/cache/template-cache /var/www/templates/cache
+chown -h www-data /var/www/templates/cache
+chgrp -h www-data /var/www/templates/cache
+
+# Link the generic cache.
+ln -nfs -T /var/cache/gen-cache /var/www/tmp/cache
+chown -h www-data /var/www/tmp/cache
+chgrp -h www-data /var/www/tmp/cache
+
+# Create the included files directory and link them
+install -d -m 700 -o www-data -g www-data /var/www/inc
+for file in /code/inc/*; do
+ file="${file##*/}"
+ if [ ! -e /var/www/inc/$file ]; then
+ ln -s /code/inc/$file /var/www/inc/
+ fi
+done
+
+# Copy an empty instance configuration if the file is a link (it was linked because it did not exist before).
+set_cfg 'instance-config.php'
+
+# Link the composer dependencies.
+ln -nfs /code/vendor /var/www/
+
+# Start the php-fpm server.
+exec php-fpm
diff --git a/docker/php/www.conf b/docker/php/www.conf
index 07fa7c28..d9d84760 100644
--- a/docker/php/www.conf
+++ b/docker/php/www.conf
@@ -1,6 +1,12 @@
[www]
-user = leftypol
-group = leftypol
+access.log = /proc/self/fd/2
+
+; Ensure worker stdout and stderr are sent to the main error log.
+catch_workers_output = yes
+
+user = www-data
+group = www-data
+
listen = 127.0.0.1:9000
pm = static
pm.max_children = 16
diff --git a/inc/template.php b/inc/template.php
index 648adae8..9ec93d34 100644
--- a/inc/template.php
+++ b/inc/template.php
@@ -13,12 +13,15 @@ $twig = false;
function load_twig() {
global $twig, $config;
+
+ $cache_dir = "{$config['dir']['template']}/cache/";
+
$loader = new Twig_Loader_Filesystem($config['dir']['template']);
$loader->setPaths($config['dir']['template']);
$twig = new Twig_Environment($loader, array(
'autoescape' => false,
- 'cache' => is_writable('templates') || (is_dir('templates/cache') && is_writable('templates/cache')) ?
- "{$config['dir']['template']}/cache" : false,
+ 'cache' => is_writable('templates/') || (is_dir($cache_dir) && is_writable($cache_dir)) ?
+ $cache_dir : false,
'debug' => $config['debug']
));
$twig->addExtension(new Twig_Extensions_Extension_Tinyboard());
@@ -27,17 +30,17 @@ function load_twig() {
function Element($templateFile, array $options) {
global $config, $debug, $twig, $build_pages;
-
+
if (!$twig)
load_twig();
-
+
if (function_exists('create_pm_header') && ((isset($options['mod']) && $options['mod']) || isset($options['__mod'])) && !preg_match('!^mod/!', $templateFile)) {
$options['pm'] = create_pm_header();
}
-
+
if (isset($options['body']) && $config['debug']) {
$_debug = $debug;
-
+
if (isset($debug['start'])) {
$_debug['time']['total'] = '~' . round((microtime(true) - $_debug['start']) * 1000, 2) . 'ms';
$_debug['time']['init'] = '~' . round(($_debug['start_debug'] - $_debug['start']) * 1000, 2) . 'ms';
@@ -55,18 +58,17 @@ function Element($templateFile, array $options) {
str_replace("\n", '
', utf8tohtml(print_r($_debug, true))) .
'';
}
-
+
// Read the template file
if (@file_get_contents("{$config['dir']['template']}/${templateFile}")) {
$body = $twig->render($templateFile, $options);
-
+
if ($config['minify_html'] && preg_match('/\.html$/', $templateFile)) {
$body = trim(preg_replace("/[\t\r\n]/", '', $body));
}
-
+
return $body;
} else {
throw new Exception("Template file '${templateFile}' does not exist or is empty in '{$config['dir']['template']}'!");
}
}
-
diff --git a/install.php b/install.php
index dfd0df73..6e58d344 100644
--- a/install.php
+++ b/install.php
@@ -1,9 +1,9 @@
= 50503)
return query($sql);
else
return query(str_replace('utf8mb4', 'utf8', $sql));
}
-
+
$boards = listBoards();
-
+
switch ($version) {
case 'v0.9':
case 'v0.9.1':
// Upgrade to v0.9.2-dev
-
+
foreach ($boards as &$_board) {
// Add `capcode` field after `trip`
query(sprintf("ALTER TABLE `posts_%s` ADD `capcode` VARCHAR( 50 ) NULL AFTER `trip`", $_board['uri'])) or error(db_error());
-
+
// Resize `trip` to 15 characters
query(sprintf("ALTER TABLE `posts_%s` CHANGE `trip` `trip` VARCHAR( 15 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL", $_board['uri'])) or error(db_error());
}
case 'v0.9.2-dev':
// Upgrade to v0.9.2-dev-1
-
+
// New table: `theme_settings`
query("CREATE TABLE IF NOT EXISTS `theme_settings` ( `name` varchar(40) NOT NULL, `value` text, UNIQUE KEY `name` (`name`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;") or error(db_error());
-
+
// New table: `news`
query("CREATE TABLE IF NOT EXISTS `news` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` text NOT NULL, `time` int(11) NOT NULL, `subject` text NOT NULL, `body` text NOT NULL, UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;") or error(db_error());
case 'v0.9.2.1-dev':
@@ -81,7 +81,7 @@ if (file_exists($config['has_installed'])) {
// Fix broken version number/mistake
$version = 'v0.9.2-dev-1';
// Upgrade to v0.9.2-dev-2
-
+
foreach ($boards as &$_board) {
// Increase field sizes
query(sprintf("ALTER TABLE `posts_%s` CHANGE `subject` `subject` VARCHAR( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL", $_board['uri'])) or error(db_error());
@@ -89,7 +89,7 @@ if (file_exists($config['has_installed'])) {
}
case 'v0.9.2-dev-2':
// Upgrade to v0.9.2-dev-3 (v0.9.2)
-
+
foreach ($boards as &$_board) {
// Add `custom_fields` field
query(sprintf("ALTER TABLE `posts_%s` ADD `embed` TEXT NULL", $_board['uri'])) or error(db_error());
@@ -97,7 +97,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':
// Upgrade to v0.9.3-dev-1
-
+
// Upgrade `theme_settings` table
query("TRUNCATE TABLE `theme_settings`") or error(db_error());
query("ALTER TABLE `theme_settings` ADD `theme` VARCHAR( 40 ) NOT NULL FIRST") or error(db_error());
@@ -129,7 +129,7 @@ if (file_exists($config['has_installed'])) {
foreach ($boards as &$board) {
$tables[] = "posts_{$board['uri']}";
}
-
+
foreach ($tables as &$table) {
query("ALTER TABLE `{$table}` ENGINE = MYISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci") or error(db_error());
}
@@ -153,10 +153,10 @@ if (file_exists($config['has_installed'])) {
query("ALTER TABLE `boards` DROP PRIMARY KEY") or error(db_error());
query("ALTER TABLE `reports` DROP INDEX `id`") or error(db_error());
query("ALTER TABLE `boards` DROP INDEX `uri`") or error(db_error());
-
+
query("ALTER IGNORE TABLE `robot` ADD PRIMARY KEY (`hash`)") or error(db_error());
query("ALTER TABLE `bans` ADD FULLTEXT (`ip`)") or error(db_error());
- query("ALTER TABLE `ip_notes` ADD INDEX (`ip`)") or error(db_error());
+ query("ALTER TABLE `ip_notes` ADD INDEX (`ip`)") or error(db_error());
query("ALTER TABLE `modlogs` ADD INDEX (`time`)") or error(db_error());
query("ALTER TABLE `boards` ADD PRIMARY KEY(`uri`)") or error(db_error());
query("ALTER TABLE `mutes` ADD INDEX (`ip`)") or error(db_error());
@@ -174,9 +174,9 @@ if (file_exists($config['has_installed'])) {
I have read and understood the agreement. Proceed to upgrading.
'; - + file_write($config['has_installed'], 'v0.9.4-dev-2'); - + break; } case 'v0.9.4-dev-3': @@ -194,14 +194,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=MyISAM DEFAULT CHARSET=utf8;") or error(db_error()); 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 `title` `title` VARCHAR( 40 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, CHANGE `subtitle` `subtitle` VARCHAR( 120 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL") or error(db_error()); case 'v0.9.5-dev-3': // v0.9.5 case 'v0.9.5': - query("ALTER TABLE `boards` + query("ALTER TABLE `boards` CHANGE `uri` `uri` VARCHAR( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, CHANGE `title` `title` TINYTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, CHANGE `subtitle` `subtitle` TINYTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL") or error(db_error()); @@ -228,12 +228,12 @@ if (file_exists($config['has_installed'])) { $query->bindValue(':newboard', $board['uri']); $query->bindValue(':oldboard', $board['id']); $query->execute() or error(db_error($query)); - + $query = prepare("UPDATE `modlogs` SET `board` = :newboard WHERE `board` = :oldboard"); $query->bindValue(':newboard', $board['uri']); $query->bindValue(':oldboard', $board['id']); $query->execute() or error(db_error($query)); - + $query = prepare("UPDATE `reports` SET `board` = :newboard WHERE `board` = :oldboard"); $query->bindValue(':newboard', $board['uri']); $query->bindValue(':oldboard', $board['id']); @@ -271,10 +271,10 @@ if (file_exists($config['has_installed'])) { if (strlen($user['password']) == 40) { mt_srand(microtime(true) * 100000 + memory_get_usage(true)); $salt = md5(uniqid(mt_rand(), true)); - + $user['salt'] = $salt; $user['password'] = hash('sha256', $user['salt'] . $user['password']); - + $_query = prepare("UPDATE `mods` SET `password` = :password, `salt` = :salt WHERE `id` = :id"); $_query->bindValue(':id', $user['id']); $_query->bindValue(':password', $user['password']); @@ -306,7 +306,7 @@ if (file_exists($config['has_installed'])) { 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()); } - + __query("ALTER TABLE `antispam` 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 , @@ -466,44 +466,44 @@ if (file_exists($config['has_installed'])) { ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1") or error(db_error()); $listquery = query("SELECT * FROM ``bans`` ORDER BY `id`") or error(db_error()); 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)"); - + $range = Bans::parse_range($ban['ip']); if ($range === false) { // Invalid retard ban; just skip it. continue; } - + $query->bindValue(':ipstart', $range[0]); if ($range[1] !== false && $range[1] != $range[0]) $query->bindValue(':ipend', $range[1]); else $query->bindValue(':ipend', null, PDO::PARAM_NULL); - + $query->bindValue(':created', $ban['set']); - + if ($ban['expires']) $query->bindValue(':expires', $ban['expires']); else $query->bindValue(':expires', null, PDO::PARAM_NULL); - + if ($ban['board']) $query->bindValue(':board', $ban['board']); else $query->bindValue(':board', null, PDO::PARAM_NULL); - + $query->bindValue(':creator', $ban['mod']); - + if ($ban['reason']) $query->bindValue(':reason', $ban['reason']); else $query->bindValue(':reason', null, PDO::PARAM_NULL); - + $query->bindValue(':seen', $ban['seen']); $query->execute() or error(db_error($query)); } - + // Drop old bans table query("DROP TABLE ``bans``") or error(db_error()); // Replace with new table @@ -535,9 +535,9 @@ if (file_exists($config['has_installed'])) {I have read and understood the agreement. Proceed to upgrading.
'; - + file_write($config['has_installed'], '4.4.97'); - + break; } case '4.4.98-pre': @@ -553,9 +553,9 @@ if (file_exists($config['has_installed'])) {I have read and understood the warning. Proceed to upgrading.
'; - + file_write($config['has_installed'], '4.5.2'); - + break; } @@ -614,7 +614,7 @@ if (file_exists($config['has_installed'])) { // Update version number file_write($config['has_installed'], VERSION); - + $page['title'] = 'Upgraded'; $page['body'] = 'Successfully upgraded from ' . $version . ' to ' . VERSION . '.
'; break; @@ -626,8 +626,8 @@ if (file_exists($config['has_installed'])) { $page['title'] = 'Already installed'; $page['body'] = 'It appears that vichan is already installed (' . $version . ') and there is nothing to upgrade! Delete ' . $config['has_installed'] . ' to reinstall.
'; break; - } - + } + die(Element('page.html', $page)); } @@ -659,11 +659,11 @@ if ($step == 0) {I have read and understood the agreement. Proceed to installation.
'; - + echo Element('page.html', $page); } elseif ($step == 1) { $page['title'] = 'Pre-installation test'; - + $can_exec = true; if (!function_exists('shell_exec')) $can_exec = false; @@ -673,12 +673,12 @@ if ($step == 0) { $can_exec = false; elseif (trim(shell_exec('echo "TEST"')) !== 'TEST') $can_exec = false; - + if (!defined('PHP_VERSION_ID')) { $version = explode('.', PHP_VERSION); define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); } - + // Required extensions $extensions = array( 'PDO' => array( @@ -818,14 +818,14 @@ if ($step == 0) { array( 'category' => 'File permissions', 'name' => getcwd() . '/templates/cache', - 'result' => is_writable('templates') || (is_dir('templates/cache') && is_writable('templates/cache')), + 'result' => is_dir('templates/cache/') && is_writable('templates/cache/'), 'required' => true, 'message' => 'You must give vichan permission to create (and write to) thetemplates/cache
directory or performance will be drastically reduced.'
),
array(
'category' => 'File permissions',
'name' => getcwd() . '/tmp/cache',
- 'result' => is_dir('tmp/cache') && is_writable('tmp/cache'),
+ 'result' => is_dir('tmp/cache/') && is_writable('tmp/cache/'),
'required' => true,
'message' => 'You must give vichan permission to write to the tmp/cache
directory.'
),
@@ -854,7 +854,7 @@ if ($step == 0) {
);
$config['font_awesome'] = true;
-
+
$additional_config = array();
foreach ($tests as $test) {
if ($test['result'] && isset($test['effect'])) {
@@ -877,10 +877,10 @@ if ($step == 0) {
} elseif ($step == 2) {
// Basic config
$page['title'] = 'Configuration';
-
+
$config['cookies']['salt'] = substr(base64_encode(sha1(rand())), 0, 30);
- $config['secure_trip_salt'] = substr(base64_encode(sha1(rand())), 0, 30);
-
+ $config['secure_trip_salt'] = substr(base64_encode(sha1(rand())), 0, 30);
+
echo Element('page.html', array(
'body' => Element('installer/config.html', array(
'config' => $config,
@@ -893,7 +893,7 @@ if ($step == 0) {
$more = $_POST['more'];
unset($_POST['more']);
- $instance_config =
+ $instance_config =
'<'.'?php
/*
@@ -905,13 +905,13 @@ if ($step == 0) {
*/
';
-
+
create_config_from_array($instance_config, $_POST);
-
+
$instance_config .= "\n";
$instance_config .= $more;
$instance_config .= "\n";
-
+
if (@file_put_contents('inc/instance-config.php', $instance_config)) {
header('Location: ?step=4', true, $config['redirect_http']);
} else {
@@ -928,22 +928,22 @@ if ($step == 0) {
}
} elseif ($step == 4) {
// SQL installation
-
+
buildJavascript();
-
+
$sql = @file_get_contents('install.sql') or error("Couldn't load install.sql.");
-
+
sql_open();
$mysql_version = mysql_version();
-
+
// This code is probably horrible, but what I'm trying
// to do is find all of the SQL queires and put them
// in an array.
preg_match_all("/(^|\n)((SET|CREATE|INSERT).+)\n\n/msU", $sql, $queries);
$queries = $queries[2];
-
+
$queries[] = Element('posts.sql', array('board' => 'b'));
-
+
$sql_errors = '';
$sql_err_count = 0;
foreach ($queries as $query) {
@@ -956,10 +956,10 @@ if ($step == 0) {
$sql_errors .= "Thank you for using vichan. Please remember to report any bugs you discover. How do I edit the config files?
'; - + if (!empty($sql_errors)) { $page['body'] .= '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.
The errors encountered were:
I couldn\'t remove install.php. You will have to remove it manually.
Thank you for using vichan. Please remember to report any bugs you discover.
'; - + $boards = listBoards(); foreach ($boards as &$_board) { setupBoard($_board); buildIndex(); } - + file_write($config['has_installed'], VERSION); if (!file_unlink(__FILE__)) { $page['body'] .= 'I couldn\'t remove install.php. You will have to remove it manually.