Compare commits

..

No commits in common. "master" and "release-3.3.15" have entirely different histories.

1750 changed files with 42413 additions and 77542 deletions

View file

@ -22,5 +22,5 @@ fi
if [ "$MYISAM" == '1' ]
then
mysql -h 127.0.0.1 -u root -e 'SET GLOBAL default_storage_engine=MyISAM;'
mysql -h 127.0.0.1 -u root -e 'SET GLOBAL storage_engine=MyISAM;'
fi

View file

@ -10,4 +10,5 @@
#
set -e
sudo apt-get update
sudo apt-get install -y parallel libimage-exiftool-perl

View file

@ -28,4 +28,9 @@ fi
cd phpBB
php ../composer.phar install --dev --no-interaction
if [[ "$PHP_VERSION" =~ ^nightly$ || "$PHP_VERSION" =~ ^8 ]]
then
php ../composer.phar remove phpunit/dbunit --dev --update-with-dependencies \
&& php ../composer.phar require symfony/yaml:~4.4 misantron/dbunit:~5.0 phpunit/phpunit:^9.3 doctrine/instantiator:^1.4 --dev --update-with-all-dependencies --ignore-platform-reqs
fi
cd ..

View file

@ -1,143 +0,0 @@
#!/bin/bash
#
# This file is part of the phpBB Forum Software package.
#
# @copyright (c) phpBB Limited <https://www.phpbb.com>
# @license GNU General Public License, version 2 (GPL-2.0)
#
# For full copyright and license information, please see
# the docs/CREDITS.txt file.
#
set -e
set -x
sudo apt-get install -q -y sphinxsearch
DIR=$(dirname "$0")
SPHINX_DAEMON_HOST="localhost"
SPHINX_DAEMON_PORT="9312"
SPHINX_CONF="$DIR/sphinx.conf"
SPHINX_DATA_DIR="/var/run/sphinxsearch"
SPHINX_LOG="$SPHINX_DATA_DIR/log/searchd.log"
SPHINX_QUERY_LOG="$SPHINX_DATA_DIR/log/sphinx-query.log"
ID="saw9zf2fdhp1goue" # Randomly generated via phpBB unique_id()
PHPBB_TEST_DBHOST="0.0.0.0"
PHPBB_TEST_DBNAME="phpbb_tests"
PHPBB_TEST_DBUSER="root"
PHPBB_TEST_DBPASSWD=""
sudo service sphinxsearch stop
sudo mkdir -p "$SPHINX_DATA_DIR/log"
sudo chown "sphinxsearch" "$SPHINX_DATA_DIR/log"
# Generate configuration file for Sphinx
echo "
source source_phpbb_${ID}_main
{
type = mysql # mysql or pgsql
sql_host = $PHPBB_TEST_DBHOST
sql_user = $PHPBB_TEST_DBUSER
sql_pass = $PHPBB_TEST_DBPASSWD
sql_db = $PHPBB_TEST_DBNAME
sql_port =
sql_query_pre = SET NAMES 'utf8'
sql_query_pre = UPDATE phpbb_sphinx SET max_doc_id = (SELECT MAX(post_id) FROM phpbb_posts) WHERE counter_id = 1
sql_query_range = SELECT MIN(post_id), MAX(post_id) FROM phpbb_posts
sql_range_step = 5000
sql_query = SELECT \
p.post_id AS id, \
p.forum_id, \
p.topic_id, \
p.poster_id, \
p.post_visibility, \
CASE WHEN p.post_id = t.topic_first_post_id THEN 1 ELSE 0 END as topic_first_post, \
p.post_time, \
p.post_subject, \
p.post_subject as title, \
p.post_text as data, \
t.topic_last_post_time, \
0 as deleted \
FROM phpbb_posts p, phpbb_topics t \
WHERE \
p.topic_id = t.topic_id \
AND p.post_id >= \$start AND p.post_id <= \$end
sql_query_post =
sql_query_post_index = UPDATE phpbb_sphinx SET max_doc_id = \$maxid WHERE counter_id = 1
sql_attr_uint = forum_id
sql_attr_uint = topic_id
sql_attr_uint = poster_id
sql_attr_uint = post_visibility
sql_attr_bool = topic_first_post
sql_attr_bool = deleted
sql_attr_timestamp = post_time
sql_attr_timestamp = topic_last_post_time
sql_attr_string = post_subject
}
source source_phpbb_${ID}_delta : source_phpbb_${ID}_main
{
sql_query_pre = SET NAMES 'utf8'
sql_query_range =
sql_range_step =
sql_query = SELECT \
p.post_id AS id, \
p.forum_id, \
p.topic_id, \
p.poster_id, \
p.post_visibility, \
CASE WHEN p.post_id = t.topic_first_post_id THEN 1 ELSE 0 END as topic_first_post, \
p.post_time, \
p.post_subject, \
p.post_subject as title, \
p.post_text as data, \
t.topic_last_post_time, \
0 as deleted \
FROM phpbb_posts p, phpbb_topics t \
WHERE \
p.topic_id = t.topic_id \
AND p.post_id >= ( SELECT max_doc_id FROM phpbb_sphinx WHERE counter_id=1 )
sql_query_post_index =
}
index index_phpbb_${ID}_main
{
path = $SPHINX_DATA_DIR/index_phpbb_${ID}_main
source = source_phpbb_${ID}_main
docinfo = extern
morphology = none
stopwords =
wordforms =
exceptions =
min_word_len = 2
charset_table = U+FF10..U+FF19->0..9, 0..9, U+FF41..U+FF5A->a..z, U+FF21..U+FF3A->a..z, A..Z->a..z, a..z, U+0149, U+017F, U+0138, U+00DF, U+00FF, U+00C0..U+00D6->U+00E0..U+00F6, U+00E0..U+00F6, U+00D8..U+00DE->U+00F8..U+00FE, U+00F8..U+00FE, U+0100->U+0101, U+0101, U+0102->U+0103, U+0103, U+0104->U+0105, U+0105, U+0106->U+0107, U+0107, U+0108->U+0109, U+0109, U+010A->U+010B, U+010B, U+010C->U+010D, U+010D, U+010E->U+010F, U+010F, U+0110->U+0111, U+0111, U+0112->U+0113, U+0113, U+0114->U+0115, U+0115, U+0116->U+0117, U+0117, U+0118->U+0119, U+0119, U+011A->U+011B, U+011B, U+011C->U+011D, U+011D, U+011E->U+011F, U+011F, U+0130->U+0131, U+0131, U+0132->U+0133, U+0133, U+0134->U+0135, U+0135, U+0136->U+0137, U+0137, U+0139->U+013A, U+013A, U+013B->U+013C, U+013C, U+013D->U+013E, U+013E, U+013F->U+0140, U+0140, U+0141->U+0142, U+0142, U+0143->U+0144, U+0144, U+0145->U+0146, U+0146, U+0147->U+0148, U+0148, U+014A->U+014B, U+014B, U+014C->U+014D, U+014D, U+014E->U+014F, U+014F, U+0150->U+0151, U+0151, U+0152->U+0153, U+0153, U+0154->U+0155, U+0155, U+0156->U+0157, U+0157, U+0158->U+0159, U+0159, U+015A->U+015B, U+015B, U+015C->U+015D, U+015D, U+015E->U+015F, U+015F, U+0160->U+0161, U+0161, U+0162->U+0163, U+0163, U+0164->U+0165, U+0165, U+0166->U+0167, U+0167, U+0168->U+0169, U+0169, U+016A->U+016B, U+016B, U+016C->U+016D, U+016D, U+016E->U+016F, U+016F, U+0170->U+0171, U+0171, U+0172->U+0173, U+0173, U+0174->U+0175, U+0175, U+0176->U+0177, U+0177, U+0178->U+00FF, U+00FF, U+0179->U+017A, U+017A, U+017B->U+017C, U+017C, U+017D->U+017E, U+017E, U+0410..U+042F->U+0430..U+044F, U+0430..U+044F, U+4E00..U+9FFF
ignore_chars = U+0027, U+002C
min_prefix_len = 3
min_infix_len = 0
html_strip = 1
index_exact_words = 0
blend_chars = U+23, U+24, U+25, U+26, U+40
}
index index_phpbb_${ID}_delta : index_phpbb_${ID}_main
{
path = $SPHINX_DATA_DIR/index_phpbb_${ID}_delta
source = source_phpbb_${ID}_delta
}
indexer
{
mem_limit = 512M
}
searchd
{
listen = $SPHINX_DAEMON_PORT
log = $SPHINX_LOG
query_log = $SPHINX_QUERY_LOG
read_timeout = 5
max_children = 30
pid_file = $SPHINX_DATA_DIR/searchd.pid
binlog_path = $SPHINX_DATA_DIR
}
" > $SPHINX_CONF
sudo mv "$SPHINX_CONF" "/etc/sphinxsearch/sphinx.conf"
sudo sed -i "s/START=no/START=yes/g" "/etc/default/sphinxsearch"
sudo chmod 777 "/var/run/sphinxsearch"

View file

@ -10,4 +10,5 @@
#
set -e
sudo apt-get update
sudo apt-get install -y expect-dev

View file

@ -11,6 +11,7 @@
set -e
set -x
sudo apt-get update
sudo apt-get install -y nginx coreutils
sudo service nginx stop

View file

@ -17,21 +17,17 @@ on:
jobs:
# Basic checks, e.g. parse errors, commit messages, etc.
basic-checks:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
strategy:
matrix:
include:
- db: 'none'
php: '8.1'
php: '7.2'
NOTESTS: 1
name: PHP ${{ matrix.php }} - ${{ matrix.db }}
steps:
- name: Update Ubuntu package lists
run: |
sudo apt-get update -y --allow-releaseinfo-change
- name: Checkout repository
uses: actions/checkout@v4
with:
@ -41,21 +37,24 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, pcntl, intl, gd, exif, iconv
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, mysqli, sqlite, pdo_sqlite, intl, gd, exif, iconv, sqlsrv, pdo_sqlsrv, ldap
coverage: none
- name: Get Composer Cache Directory
id: composer-cache
env:
PHP_VERSION: ${{ matrix.php }}
run: |
cd phpBB
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
echo "version=${PHP_VERSION%.*}" >> $GITHUB_OUTPUT
cd ..
- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: composer-${{ matrix.php }}-${{ hashFiles('phpBB/composer.lock') }}
key: composer-${{ steps.composer-cache.outputs.version }}-${{ hashFiles('phpBB/composer.lock') }}
- name: Setup environment for phpBB
env:
@ -73,10 +72,6 @@ jobs:
run: |
.github/check-doctum-parse-errors.sh
- name: Check code with psalm
run: |
phpBB/vendor/bin/psalm --output-format=github
- name: Check image ICC profiles
run: |
.github/check-image-icc-profiles.sh
@ -85,14 +80,6 @@ jobs:
run: |
.github/check-executable-files.sh ./
- name: Check stylesheets
run: |
.github/check-stylesheet.sh
- name: Lint JavaScript files
run: |
.github/check-js.sh
- name: Check commit message
if: github.event_name == 'pull_request'
run: |
@ -101,50 +88,48 @@ jobs:
# Tests for MySQL and MariaDB
mysql-tests:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
strategy:
matrix:
include:
- php: '8.1'
- php: '7.2'
db: "mariadb:10.1"
- php: '7.2'
db: "mariadb:10.2"
- php: '8.1'
- php: '7.2'
db: "mariadb:10.3"
- php: '8.1'
- php: '7.2'
db: "mariadb:10.4"
- php: '8.1'
db: "mariadb:10.6"
- php: '8.1'
db: "mariadb:10.9"
- php: '8.1'
db: "mariadb:10.10"
- php: '8.1'
db: "mariadb:10.11"
- php: '8.1'
db: "mysql:5.7"
- php: '7.2'
db: "mariadb:10.5"
- php: '7.2'
db: "mysql:5.6"
db_alias: "MySQL Slow Tests"
SLOWTESTS: 1
- php: '8.1'
db: "mysql:5.7"
- php: '7.2'
db: "mysql:5.6"
db_alias: "MyISAM Tests"
MYISAM: 1
- php: '8.1'
- php: '7.2'
db: "mysql:5.6"
- php: '7.2'
db: "mysql:5.7"
- php: '7.3'
db: "mysql:5.7"
- php: '7.4'
db: "mysql:5.7"
- php: '7.4'
db: "mysql:8.0"
- php: '8.0'
db: "mysql:5.7"
- php: '8.1'
db: "mysql:8.0"
- php: '8.1'
db: "mysql:8.1"
db: "mysql:5.7"
- php: '8.2'
db: "mysql:8.0"
- php: '8.2'
db: "mariadb:10.2"
- php: '8.3'
db: "mysql:5.7"
- php: '8.3'
db: "mariadb:10.2"
db: "mysql:5.7"
- php: '8.4'
db: "mysql:8.0"
- php: '8.4'
db: "mariadb:10.3"
db: "mysql:5.7"
name: PHP ${{ matrix.php }} - ${{ matrix.db_alias != '' && matrix.db_alias || matrix.db }}
@ -173,10 +158,6 @@ jobs:
- 6379:6379
steps:
- name: Update Ubuntu package lists
run: |
sudo apt-get update -y --allow-releaseinfo-change
- name: Checkout repository
uses: actions/checkout@v4
@ -191,7 +172,7 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, pcntl, intl, gd, exif, iconv, mysqli, pdo, pdo_mysql, ldap
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, mysqli, sqlite, pdo_sqlite, intl, gd, exif, iconv, sqlsrv, pdo_sqlsrv, ldap
coverage: none
- name: Get Composer Cache Directory
@ -201,13 +182,14 @@ jobs:
run: |
cd phpBB
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
echo "version=${PHP_VERSION%.*}" >> $GITHUB_OUTPUT
cd ..
- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: composer-${{ matrix.php }}-${{ hashFiles('phpBB/composer.lock') }}
key: composer-${{ steps.composer-cache.outputs.version }}-${{ hashFiles('phpBB/composer.lock') }}
- name: Setup environment for phpBB
env:
@ -229,17 +211,6 @@ jobs:
run: |
.github/setup-ldap.sh
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Setup node dependencies
run: npm ci
- name: Setup SPHINX
run: |
.github/setup-sphinx.sh
- name: Lint tests
if: ${{ matrix.SLOWTESTS != 1 && steps.database-type.outputs.db == 'mysql' }}
run: phpBB/vendor/bin/phpunit tests/lint_test.php
@ -260,38 +231,46 @@ jobs:
# Tests for PostgreSQL
postgres-tests:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
strategy:
matrix:
include:
- php: '8.1'
- php: '7.2'
db: "postgres:9.3"
- php: '7.2'
db: "postgres:9.5"
- php: '8.1'
- php: '7.2'
db: "postgres:9.6"
- php: '8.1'
- php: '7.2'
db: "postgres:10"
- php: '8.1'
- php: '7.2'
db: "postgres:11"
- php: '8.1'
- php: '7.2'
db: "postgres:12"
- php: '8.1'
- php: '7.2'
db: "postgres:13"
- php: '7.3'
db: "postgres:13"
- php: '7.4'
db: "postgres:13"
- php: '8.0'
db: "postgres:12"
- php: '8.0'
db: "postgres:13"
- php: '8.1'
db: "postgres:14"
- php: '8.1'
db: "postgres:15"
- php: '8.2'
db: "postgres:9.5"
db: "postgres:14"
- php: '8.3'
db: "postgres:9.5"
db: "postgres:14"
- php: '8.4'
db: "postgres:9.5"
db: "postgres:14"
name: PHP ${{ matrix.php }} - ${{ matrix.db }}
services:
postgres:
image: ${{ matrix.db != 'postgres:9.5' && matrix.db != 'postgres:9.6' && matrix.db != 'postgres:10' && matrix.db != 'postgres:11' && matrix.db != 'postgres:12' && matrix.db != 'postgres:13' && matrix.db != 'postgres:14' && matrix.db != 'postgres:15' && 'postgres:10' || matrix.db }}
image: ${{ matrix.db != 'postgres:9.3' && matrix.db != 'postgres:9.5' && matrix.db != 'postgres:9.6' && matrix.db != 'postgres:10' && matrix.db != 'postgres:11' && matrix.db != 'postgres:12' && matrix.db != 'postgres:13' && 'postgres:10' || matrix.db }}
env:
POSTGRES_HOST: localhost
POSTGRES_USER: postgres
@ -316,10 +295,6 @@ jobs:
- 6379:6379
steps:
- name: Update Ubuntu package lists
run: |
sudo apt-get update -y --allow-releaseinfo-change
- name: Checkout repository
uses: actions/checkout@v4
@ -334,7 +309,7 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, pcntl, intl, gd, exif, iconv, pgsql, pdo, pdo_pgsql
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, mysqli, sqlite, pdo_sqlite, intl, gd, exif, iconv, sqlsrv, pdo_sqlsrv, ldap
coverage: none
- name: Get Composer Cache Directory
@ -344,13 +319,14 @@ jobs:
run: |
cd phpBB
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
echo "version=${PHP_VERSION%.*}" >> $GITHUB_OUTPUT
cd ..
- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: composer-${{ matrix.php }}-${{ hashFiles('phpBB/composer.lock') }}
key: composer-${{ steps.composer-cache.outputs.version }}-${{ hashFiles('phpBB/composer.lock') }}
- name: Setup environment for phpBB
env:
@ -367,13 +343,6 @@ jobs:
run: |
.github/setup-database.sh $DB $MYISAM
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Setup node dependencies
run: npm ci
- name: Run unit tests
env:
DB: ${{steps.database-type.outputs.db}}
@ -382,24 +351,24 @@ jobs:
# Other database types, namely sqlite3 and mssql
other-tests:
runs-on: ubuntu-22.04
runs-on: ubuntu-20.04
strategy:
matrix:
include:
- php: '8.1'
- php: '7.2'
db: "sqlite3"
- php: '8.1'
- php: '7.2'
db: "mcr.microsoft.com/mssql/server:2017-latest"
db_alias: 'MSSQL 2017'
- php: '7.2'
db: "mcr.microsoft.com/mssql/server:2019-CU27-ubuntu-20.04"
db_alias: 'MSSQL 2019'
- php: '8.1'
db: "mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04"
db_alias: 'MSSQL 2022'
name: PHP ${{ matrix.php }} - ${{ matrix.db_alias != '' && matrix.db_alias || matrix.db }}
services:
mssql:
image: ${{ matrix.db != 'mcr.microsoft.com/mssql/server:2019-CU27-ubuntu-20.04' && matrix.db != 'mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04' && 'mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04' || matrix.db }}
image: ${{ matrix.db != 'mcr.microsoft.com/mssql/server:2017-latest' && matrix.db != 'mcr.microsoft.com/mssql/server:2019-CU27-ubuntu-20.04' && 'mcr.microsoft.com/mssql/server:2017-latest' || matrix.db }}
env:
SA_PASSWORD: "Pssw0rd_12"
ACCEPT_EULA: "y"
@ -424,10 +393,6 @@ jobs:
steps:
- name: Update Ubuntu package lists
run: |
sudo apt-get update -y --allow-releaseinfo-change
- name: Checkout repository
uses: actions/checkout@v4
@ -435,7 +400,7 @@ jobs:
env:
MATRIX_DB: ${{ matrix.db }}
run: |
if [ $MATRIX_DB == 'mcr.microsoft.com/mssql/server:2019-CU27-ubuntu-20.04' ] || [ $MATRIX_DB == 'mcr.microsoft.com/mssql/server:2022-CU13-ubuntu-22.04' ]
if [ $MATRIX_DB == 'mcr.microsoft.com/mssql/server:2017-latest' ] || [ $MATRIX_DB == 'mcr.microsoft.com/mssql/server:2019-CU27-ubuntu-20.04' ]
then
db='mssql'
else
@ -447,7 +412,7 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, pcntl, intl, gd, exif, iconv, sqlsrv, pdo, pdo_sqlsrv
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, mysqli, sqlite, pdo_sqlite, intl, gd, exif, iconv, sqlsrv, pdo_sqlsrv, ldap
coverage: none
- name: Get Composer Cache Directory
@ -457,13 +422,14 @@ jobs:
run: |
cd phpBB
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
echo "version=${PHP_VERSION%.*}" >> $GITHUB_OUTPUT
cd ..
- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: composer-${{ matrix.php }}-${{ hashFiles('phpBB/composer.lock') }}
key: composer-${{ steps.composer-cache.outputs.version }}-${{ hashFiles('phpBB/composer.lock') }}
- name: Setup environment for phpBB
env:
@ -480,13 +446,6 @@ jobs:
run: |
.github/setup-database.sh $DB $MYISAM
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Setup node dependencies
run: npm ci
- name: Run unit tests
env:
DB: ${{steps.database-type.outputs.db}}
@ -498,11 +457,45 @@ jobs:
runs-on: windows-latest
strategy:
matrix:
type: ['unit', 'functional']
php: ['8.1', '8.2', '8.3']
db: ['postgres']
include:
- php: '7.4'
db: "postgres"
type: 'unit'
- php: '8.0'
db: "postgres"
type: 'unit'
- php: '8.1'
db: "postgres"
type: 'unit'
- php: '8.2'
db: "postgres"
type: 'unit'
- php: '8.3'
db: "postgres"
type: 'unit'
- php: '8.4'
db: "postgres"
type: 'unit'
- php: '7.4'
db: "postgres"
type: 'functional'
- php: '8.0'
db: "postgres"
type: 'functional'
- php: '8.1'
db: "postgres"
type: 'functional'
- php: '8.2'
db: "postgres"
type: 'functional'
- php: '8.3'
db: "postgres"
type: 'functional'
- php: '8.4'
db: "postgres"
type: 'functional'
name: Windows - ${{ matrix.type }} - PHP ${{ matrix.php }} - ${{ matrix.db }}
name: Windows - PHP ${{ matrix.php }} - ${{ matrix.db }} - ${{ matrix.type }}
steps:
- name: Prepare git for Windows
@ -516,7 +509,7 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, intl, gd, exif, iconv, pgsql, pdo_pgsql, sodium
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, intl, gd, exif, iconv, pgsql, pdo_pgsql
ini-values: upload_tmp_dir=${{ runner.temp }}, sys_temp_dir=${{ runner.temp }}
coverage: none
@ -525,13 +518,15 @@ jobs:
run: |
cd phpBB
echo "dir=$(composer config cache-files-dir)" >> $env:GITHUB_OUTPUT
$major_version="${{ matrix.php }}".substring(0,1)
echo "version=$major_version" >> $env:GITHUB_OUTPUT
cd ..
- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: composer-${{ matrix.php }}-${{ hashFiles('phpBB/composer.lock') }}
key: composer-${{ steps.composer-cache.outputs.version }}-${{ hashFiles('phpBB/composer.lock') }}
- name: Setup environment for phpBB
env:
@ -563,10 +558,6 @@ jobs:
icacls "${env:GITHUB_WORKSPACE}\phpBB\cache" /grant Users:F /T
icacls "${env:GITHUB_WORKSPACE}\phpBB\files" /grant Users:F /T
icacls "${env:GITHUB_WORKSPACE}\phpBB\store" /grant Users:F /T
icacls "${env:GITHUB_WORKSPACE}\phpBB\ext" /grant Users:F /T
icacls "${env:GITHUB_WORKSPACE}\phpBB\vendor-ext" /grant Users:F /T
icacls "${env:GITHUB_WORKSPACE}\phpBB\composer-ext.json" /grant Users:F /T
icacls "${env:GITHUB_WORKSPACE}\phpBB\composer-ext.lock" /grant Users:F /T
icacls "${env:GITHUB_WORKSPACE}\phpBB\images\avatars\upload" /grant Users:F /T
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("IIS_IUSRS", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")
$acl = Get-ACL "${env:TEMP_DIR}"
@ -574,6 +565,8 @@ jobs:
Set-ACL -Path "${env:TEMP_DIR}" -ACLObject $acl
cd ${env:GITHUB_WORKSPACE}\phpBB
php ..\composer.phar install
php ..\composer.phar remove phpunit/dbunit --dev --update-with-dependencies
php ..\composer.phar require symfony/yaml:~4.4 misantron/dbunit:~5.0 phpunit/phpunit:^9.3 doctrine/instantiator:^1.4 --dev --update-with-all-dependencies --ignore-platform-reqs
cd ..
- name: Setup database
run: |
@ -595,19 +588,11 @@ jobs:
psql -c 'create database phpbb_tests;' -U postgres
Set-MpPreference -ExclusionPath "${env:PGDATA}" # Exclude PGDATA directory from Windows Defender
Set-MpPreference -DisableRealtimeMonitoring $true
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Setup node dependencies
run: npm ci
- name: Run unit tests
if: ${{ matrix.type == 'unit' }}
run: |
phpBB/vendor/bin/phpunit --configuration .github/phpunit-psql-windows-github.xml --verbose --stop-on-error --exclude-group functional,slow
- name: Run functional tests
phpBB/vendor/bin/phpunit --configuration .github/phpunit-psql-windows-github.xml --verbose --stop-on-error --exclude-group functional
- name: Run unit tests
if: ${{ matrix.type == 'functional' }}
run: |
phpBB/vendor/bin/phpunit --configuration .github/phpunit-psql-windows-github.xml --verbose --stop-on-error --group functional

7
.gitignore vendored
View file

@ -19,6 +19,7 @@
# Excludes all custom styles
/phpBB/styles/*
!/phpBB/styles/prosilver
/phpBB/styles/prosilver/theme/*/
!/phpBB/styles/prosilver/theme/en
!/phpBB/styles/prosilver/theme/images
!/phpBB/styles/all
@ -34,14 +35,9 @@
# Excludes vendors
/phpBB/vendor
/phpBB/vendor-ext/*
!/phpBB/vendor-ext/.git-keep
/phpBB/composer-ext.json
/phpBB/composer-ext.lock
# Excludes test / dev files
/phpunit.xml
/.phpunit.result.cache
/phpBB/composer.phar
/tests/phpbb_unit_tests.sqlite*
/tests/test_config*.php
@ -50,7 +46,6 @@
/vagrant/phpbb-install-config.yml
.vagrant
node_modules
/build/package_signature
# Excludes IDE / editors files
*~

78
.jscsrc Normal file
View file

@ -0,0 +1,78 @@
{
"excludeFiles": ["node_modules/**", "**/build/**"],
"requireCurlyBraces": [
"if", "else", "for", "while", "do", "try", "catch"
],
"requireSpaceBeforeKeywords": [
"else", "while", "catch"
],
"requireSpaceAfterKeywords": [
"do", "for", "if", "else", "switch", "case", "try", "catch", "while", "return", "typeof"
],
"requireSpaceBeforeBlockStatements": true,
"requireParenthesesAroundIIFE": true,
"requireSpacesInConditionalExpression": {
"afterTest": true,
"beforeConsequent": true,
"afterConsequent": true,
"beforeAlternate": true
},
"requireSpacesInAnonymousFunctionExpression": {
"beforeOpeningCurlyBrace": true
},
"disallowSpacesInNamedFunctionExpression": {
"beforeOpeningRoundBrace": true
},
"requireSpacesInFunction": {
"beforeOpeningCurlyBrace": true
},
"disallowSpacesInCallExpression": true,
"requireBlocksOnNewline": true,
"requirePaddingNewlinesBeforeKeywords": ["case"],
"disallowEmptyBlocks": true,
"disallowSpacesInsideArrayBrackets": "nested",
"disallowSpacesInsideParentheses": true,
"requireSpacesInsideObjectBrackets": "all",
"disallowQuotedKeysInObjects": "allButReserved",
"disallowSpaceAfterObjectKeys": true,
"requireSpaceBeforeObjectValues": true,
"requireCommaBeforeLineBreak": true,
"requireOperatorBeforeLineBreak": [
"?", "=", "+", "-", "/", "*", "===", "!==", ">", ">=", "<", "<="
],
"disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
"disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
"requireSpaceBeforeBinaryOperators": [
"=", "+", "+=", "-", "-=", "/", "/=", "*", "*=", "===", "!==", "<", "<=", ">", ">="
],
"requireSpaceAfterBinaryOperators": [
"=", "+", "+=", "-", "-=", "/", "/=", "*", "*=", "===", "!==", "<", "<=", ">", ">="
],
"disallowKeywords": ["with"],
"disallowMultipleLineStrings": true,
"disallowMixedSpacesAndTabs": "smart",
"disallowTrailingWhitespace": true,
"disallowTrailingComma": true,
"disallowKeywordsOnNewLine": ["else"],
"requireLineFeedAtFileEnd": true,
"maximumLineLength": {
"value": 120,
"tabSize": 4,
"allowUrlComments": true,
"allowRegex": true
},
"requireCapitalizedConstructors": true,
"requireDotNotation": true,
"disallowYodaConditions": true,
"requireSpaceAfterLineComment": {
"allExcept": ["#", "="]
},
"disallowNewlineBeforeBlockStatements": true,
"validateQuoteMarks": {
"mark": "'",
"escape": true
},
"validateParameterSeparator": ", ",
"safeContextKeyword": ["that"]
}

25
.jshintrc Normal file
View file

@ -0,0 +1,25 @@
{
"bitwise": true,
"curly": true,
"eqeqeq": true,
"es3": true,
"forin": false,
"freeze": true,
"newcap": true,
"noarg": true,
"noempty": true,
"nonbsp": true,
"undef": true,
"unused": true,
"strict": true,
"browser": true,
"devel": true,
"jquery": true,
"globals": {
"JSON": true,
"phpbb": true
}
}

View file

@ -1,206 +0,0 @@
{
"order": [
"custom-properties",
"dollar-variables",
{
"type": "at-rule",
"name": "include"
},
"declarations",
"rules",
{
"type": "at-rule",
"name": "media"
}
],
"properties-order": [
"font",
"font-family",
"font-size",
"font-weight",
"font-style",
"font-variant",
"font-size-adjust",
"font-stretch",
"font-effect",
"font-emphasize",
"font-emphasize-position",
"font-emphasize-style",
"font-smooth",
"font-smoothing",
"line-height",
"text-align",
"text-align-last",
"vertical-align",
"white-space",
"text-decoration",
"text-emphasis",
"text-emphasis-color",
"text-emphasis-style",
"text-emphasis-position",
"text-indent",
"text-justify",
"letter-spacing",
"word-spacing",
"writing-mode",
"text-outline",
"text-transform",
"text-size-adjust",
"text-wrap",
"text-overflow",
"text-overflow-ellipsis",
"text-overflow-mode",
"word-wrap",
"word-break",
"tab-size",
"hyphens",
"background",
"background-color",
"background-image",
"background-repeat",
"background-attachment",
"background-position",
"background-position-x",
"background-position-y",
"background-clip",
"background-origin",
"background-size",
"interpolation-mode",
"filter",
"border",
"border-width",
"border-style",
"border-color",
"border-top",
"border-top-width",
"border-top-style",
"border-top-color",
"border-right",
"border-right-width",
"border-right-style",
"border-right-color",
"border-bottom",
"border-bottom-width",
"border-bottom-style",
"border-bottom-color",
"border-left",
"border-left-width",
"border-left-style",
"border-left-color",
"border-radius",
"border-top-left-radius",
"border-top-right-radius",
"border-bottom-right-radius",
"border-bottom-left-radius",
"border-image",
"border-image-source",
"border-image-slice",
"border-image-width",
"border-image-outset",
"border-image-repeat",
"outline",
"outline-width",
"outline-style",
"outline-color",
"outline-offset",
"tap-highlight-color",
"box-decoration-break",
"box-shadow",
"text-shadow",
"color",
"opacity",
"position",
"z-index",
"top",
"right",
"bottom",
"left",
"display",
"visibility",
"float",
"clear",
"overflow",
"overflow-x",
"overflow-y",
"overflow-scrolling",
"clip",
"zoom",
"flex",
"flex-direction",
"flex-order",
"flex-pack",
"flex-align",
"flex-grow",
"flex-shrink",
"flex-basis",
"flex-wrap",
"justify-content",
"align-items",
"align-self",
"box-sizing",
"width",
"min-width",
"max-width",
"height",
"min-height",
"max-height",
"margin",
"margin-top",
"margin-right",
"margin-bottom",
"margin-left",
"padding",
"padding-top",
"padding-right",
"padding-bottom",
"padding-left",
"table-layout",
"empty-cells",
"caption-side",
"border-spacing",
"border-collapse",
"list-style",
"list-style-position",
"list-style-type",
"list-style-image",
"content",
"quotes",
"counter-reset",
"counter-increment",
"resize",
"cursor",
"touch-callout",
"touch-action",
"user-select",
"nav-index",
"nav-up",
"nav-right",
"nav-down",
"nav-left",
"transition",
"transition-delay",
"transition-timing-function",
"transition-duration",
"transition-property",
"transform",
"transform-origin",
"animation",
"animation-name",
"animation-duration",
"animation-play-state",
"animation-timing-function",
"animation-delay",
"animation-iteration-count",
"animation-direction",
"pointer-events"
],
"unspecified-properties-position": "bottomAlphabetical"
}

View file

@ -1,397 +0,0 @@
{
"plugins": [
"stylelint-order"
],
"ignoreFiles": [
"./phpBB/styles/prosilver/theme/normalize.css"
],
"rules": {
"at-rule-name-case": "lower",
"at-rule-name-newline-after": "always-multi-line",
"at-rule-name-space-after": "always-single-line",
"at-rule-no-vendor-prefix": true,
"at-rule-semicolon-newline-after": "always",
"block-closing-brace-newline-after": [
"always", {
"ignoreAtRules": ["if", "else"]
}
],
"block-closing-brace-newline-before": "always-multi-line",
"block-closing-brace-space-before": "always-single-line",
"block-no-empty": true,
"block-opening-brace-newline-after": "always-multi-line",
"block-opening-brace-space-after": "always-single-line",
"block-opening-brace-space-before": "always",
"color-hex-case": "lower",
"color-hex-length": "long",
"color-named": "never",
"color-no-invalid-hex": true,
"comment-empty-line-before": [
"always", {
"except": ["first-nested"],
"ignore": ["stylelint-commands"]
}
],
"comment-whitespace-inside": "always",
"declaration-bang-space-after": "never",
"declaration-bang-space-before": "always",
"declaration-block-no-shorthand-property-overrides": true,
"declaration-block-semicolon-newline-after": "always-multi-line",
"declaration-block-semicolon-newline-before": "never-multi-line",
"declaration-block-semicolon-space-after": "always-single-line",
"declaration-block-semicolon-space-before": "never",
"declaration-block-trailing-semicolon": "always",
"declaration-block-single-line-max-declarations": 1,
"declaration-block-no-duplicate-properties": [
true, {
"ignore": ["consecutive-duplicates-with-different-values"]
}
],
"declaration-colon-newline-after": "always-multi-line",
"declaration-colon-space-after": "always-single-line",
"declaration-colon-space-before": "never",
"declaration-empty-line-before": "never",
"declaration-property-unit-disallowed-list": {
"line-height": ["rem", "em", "%"]
},
"declaration-property-unit-allowed-list": {
"height": ["px", "%", "vh"],
"width": ["px", "%", "vw"],
"font-size": ["px", "rem", "%"],
"margin-left": ["px", "rem", "%"],
"margin-right": ["px", "rem", "%"],
"margin-top": ["px", "rem", "%"],
"margin-bottom": ["px", "rem", "%"],
"padding-left": ["px", "rem"],
"padding-right": ["px", "rem"],
"padding-top": ["px", "rem"],
"padding-bottom": ["px", "rem"],
"letter-spacing": ["em"],
"word-spacing": ["em"]
},
"font-family-name-quotes": "always-where-recommended",
"function-calc-no-unspaced-operator": true,
"function-comma-newline-after": "never-multi-line",
"function-comma-newline-before": "never-multi-line",
"function-comma-space-after": "always-single-line",
"function-comma-space-before": "never-single-line",
"function-linear-gradient-no-nonstandard-direction": true,
"function-max-empty-lines": 5,
"function-name-case": "lower",
"function-parentheses-newline-inside": "always-multi-line",
"function-parentheses-space-inside": "never-single-line",
"function-url-quotes": "always",
"function-whitespace-after": "always",
"indentation": "tab",
"length-zero-no-unit": true,
"max-empty-lines": 10,
"max-line-length": 180,
"max-nesting-depth": 4,
"media-feature-colon-space-after": "always",
"media-feature-colon-space-before": "never",
"media-feature-name-case": "lower",
"media-feature-parentheses-space-inside": "never",
"media-feature-range-operator-space-after": "always",
"media-feature-range-operator-space-before": "always",
"media-query-list-comma-newline-after": "always-multi-line",
"media-query-list-comma-newline-before": "never-multi-line",
"media-query-list-comma-space-after": "always-single-line",
"media-query-list-comma-space-before": "never",
"no-duplicate-selectors": true,
"no-empty-source": true,
"no-eol-whitespace": true,
"no-extra-semicolons": true,
"no-missing-end-of-source-newline": true,
"no-unknown-animations": true,
"number-leading-zero": "always",
"number-max-precision": 10,
"number-no-trailing-zeros": true,
"property-case": "lower",
"property-no-unknown": true,
"rule-empty-line-before": ["always-multi-line", {
"ignore": ["after-comment"],
"except": ["first-nested"]
}],
"selector-attribute-brackets-space-inside": "never",
"selector-attribute-operator-space-after": "never",
"selector-attribute-operator-space-before": "never",
"selector-attribute-quotes": "always",
"selector-combinator-space-after": "always",
"selector-combinator-space-before": "always",
"selector-list-comma-newline-after": "always",
"selector-list-comma-space-before": "never",
"selector-max-empty-lines": 5,
"selector-max-compound-selectors": 5,
"selector-pseudo-class-case": "lower",
"selector-pseudo-class-no-unknown": true,
"selector-pseudo-class-parentheses-space-inside": "never",
"selector-pseudo-element-case": "lower",
"selector-pseudo-element-colon-notation": "single",
"selector-pseudo-element-no-unknown": true,
"selector-type-case": "lower",
"selector-type-no-unknown": true,
"selector-descendant-combinator-no-non-space": true,
"selector-max-id": 0,
"selector-no-qualifying-type": [
true, {
"ignore": ["attribute"]
}
],
"shorthand-property-no-redundant-values": true,
"string-no-newline": true,
"string-quotes": "double",
"unit-case": "lower",
"unit-no-unknown": true,
"value-list-comma-newline-after": "always-multi-line",
"value-list-comma-newline-before": "never-multi-line",
"value-list-comma-space-after": "always-single-line",
"value-list-comma-space-before": "never",
"order/order": [
"custom-properties",
"dollar-variables",
{
"type": "at-rule",
"name": "include",
"parameter": "type"
},
"declarations",
"rules",
{
"type": "at-rule",
"name": "include",
"parameter": "fluid"
},
{
"type": "at-rule",
"name": "media"
}
],
"order/properties-order": [
[
"font",
"font-family",
"font-size",
"font-weight",
"font-style",
"font-variant",
"font-size-adjust",
"font-stretch",
"font-effect",
"font-emphasize",
"font-emphasize-position",
"font-emphasize-style",
"font-smooth",
"font-smoothing",
"line-height",
"text-align",
"text-align-last",
"vertical-align",
"white-space",
"text-decoration",
"text-emphasis",
"text-emphasis-color",
"text-emphasis-style",
"text-emphasis-position",
"text-indent",
"text-justify",
"letter-spacing",
"word-spacing",
"writing-mode",
"text-outline",
"text-transform",
"text-size-adjust",
"text-wrap",
"text-overflow",
"text-overflow-ellipsis",
"text-overflow-mode",
"word-wrap",
"word-break",
"tab-size",
"hyphens",
"background",
"background-color",
"background-image",
"background-repeat",
"background-attachment",
"background-position",
"background-position-x",
"background-position-y",
"background-clip",
"background-origin",
"background-size",
"interpolation-mode",
"filter",
"border",
"border-width",
"border-style",
"border-color",
"border-top",
"border-top-width",
"border-top-style",
"border-top-color",
"border-right",
"border-right-width",
"border-right-style",
"border-right-color",
"border-bottom",
"border-bottom-width",
"border-bottom-style",
"border-bottom-color",
"border-left",
"border-left-width",
"border-left-style",
"border-left-color",
"border-radius",
"border-top-left-radius",
"border-top-right-radius",
"border-bottom-right-radius",
"border-bottom-left-radius",
"border-image",
"border-image-source",
"border-image-slice",
"border-image-width",
"border-image-outset",
"border-image-repeat",
"outline",
"outline-width",
"outline-style",
"outline-color",
"outline-offset",
"tap-highlight-color",
"box-decoration-break",
"box-shadow",
"text-shadow",
"color",
"opacity",
"position",
"z-index",
"top",
"right",
"bottom",
"left",
"display",
"visibility",
"float",
"clear",
"overflow",
"overflow-x",
"overflow-y",
"overflow-scrolling",
"clip",
"zoom",
"flex",
"flex-direction",
"flex-order",
"flex-pack",
"flex-align",
"flex-basis",
"flex-grow",
"flex-shrink",
"flex-wrap",
"justify-content",
"align-items",
"align-self",
"box-sizing",
"width",
"min-width",
"max-width",
"height",
"min-height",
"max-height",
"margin",
"margin-top",
"margin-right",
"margin-bottom",
"margin-left",
"padding",
"padding-top",
"padding-right",
"padding-bottom",
"padding-left",
"table-layout",
"empty-cells",
"caption-side",
"border-spacing",
"border-collapse",
"list-style",
"list-style-position",
"list-style-type",
"list-style-image",
"content",
"quotes",
"counter-reset",
"counter-increment",
"resize",
"cursor",
"touch-callout",
"touch-action",
"user-select",
"nav-index",
"nav-up",
"nav-right",
"nav-down",
"nav-left",
"transition",
"transition-delay",
"transition-timing-function",
"transition-duration",
"transition-property",
"transform",
"transform-origin",
"animation",
"animation-name",
"animation-duration",
"animation-play-state",
"animation-timing-function",
"animation-delay",
"animation-iteration-count",
"animation-direction",
"pointer-events"
],
{ "unspecified": "bottomAlphabetical" }
]
}
}

6
Vagrantfile vendored
View file

@ -11,15 +11,15 @@ aliasesPath = "vagrant/aliases"
require File.expand_path(confDir + '/scripts/homestead.rb')
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
if File.exist? aliasesPath then
if File.exists? aliasesPath then
config.vm.provision "file", source: aliasesPath, destination: "~/.bash_aliases"
end
if File.exist? homesteadYamlPath then
if File.exists? homesteadYamlPath then
Homestead.configure(config, YAML::load(File.read(homesteadYamlPath)))
end
if File.exist? afterScriptPath then
if File.exists? afterScriptPath then
config.vm.provision "shell", path: afterScriptPath
end
end

View file

@ -2,9 +2,9 @@
<project name="phpBB" description="The phpBB forum software" default="all" basedir="../">
<!-- a few settings for the build -->
<property name="newversion" value="4.0.0-a1-dev" />
<property name="prevversion" value="3.3.15" />
<property name="olderversions" value="3.1.12, 3.2.11, 3.3.0, 3.3.1, 3.3.2, 3.3.3, 3.3.4, 3.3.5, 3.3.6, 3.3.7, 3.3.8, 3.3.9, 3.3.10, 3.3.11, 3.3.12, 3.3.13, 3.3.14" />
<property name="newversion" value="3.3.15" />
<property name="prevversion" value="3.3.14" />
<property name="olderversions" value="3.1.0, 3.1.1, 3.1.2, 3.1.3, 3.1.4, 3.1.5, 3.1.6, 3.1.7, 3.1.7-pl1, 3.1.8, 3.1.9, 3.1.10, 3.1.11, 3.1.12, 3.2.0, 3.2.1, 3.2.2, 3.2.3, 3.2.4, 3.2.5, 3.2.6, 3.2.7, 3.2.8, 3.2.9, 3.2.10, 3.2.11, 3.3.0, 3.3.1, 3.3.2, 3.3.3, 3.3.4, 3.3.5, 3.3.6, 3.3.7, 3.3.8, 3.3.9, 3.3.10, 3.3.11, 3.3.12, 3.3.13, 3.3.15-RC1" />
<!-- no configuration should be needed beyond this point -->
<property name="oldversions" value="${olderversions}, ${prevversion}" />
@ -166,32 +166,32 @@
<target name="prepare-new-version">
<!-- select the currently checked out commit (HEAD) for packaging -->
<mkdir dir="build/new_version/phpBB" />
<mkdir dir="build/new_version/phpBB3" />
<phingcall target="export">
<property name="revision" value="HEAD" />
<property name="dir" value="build/new_version/phpBB" />
<property name="dir" value="build/new_version/phpBB3" />
</phingcall>
<!-- copy into directory for diffs -->
<exec dir="build" command="cp -rp new_version/phpBB old_versions/release-${newversion}" />
<exec dir="build" command="cp -rp new_version/phpBB3 old_versions/release-${newversion}" />
<!-- and clean up -->
<phingcall target="clean-diff-dir">
<property name="dir" value="build/old_versions/release-${newversion}" />
</phingcall>
<!-- create an empty config.php file (not for diffs) -->
<touch file="build/new_version/phpBB/config.php" />
<copy file="build/new_version/phpBB/vendor-ext/.htaccess" tofile="build/new_version/phpBB/vendor/.htaccess" />
<touch file="build/new_version/phpBB3/config.php" />
<copy file="build/new_version/phpBB3/phpbb/.htaccess" tofile="build/new_version/phpBB3/vendor/.htaccess" />
</target>
<target name="package" depends="clean,prepare,prepare-new-version,old-version-diffs">
<exec dir="build" command="php -f package.php '${versions}' > logs/package.log" escape="false" />
<exec dir="build" escape="false"
command="LC_ALL=C diff -crNEBZbd old_versions/release-${prevversion}/language new_version/phpBB/language >
command="LC_ALL=C diff -crNEBZbd old_versions/release-${prevversion}/language new_version/phpBB3/language >
save/phpbb-${prevversion}_to_${newversion}_language.patch" />
<exec dir="build" escape="false"
command="LC_ALL=C diff -crNEBZbd old_versions/release-${prevversion}/styles/prosilver new_version/phpBB/styles/prosilver >
command="LC_ALL=C diff -crNEBZbd old_versions/release-${prevversion}/styles/prosilver new_version/phpBB3/styles/prosilver >
save/phpbb-${prevversion}_to_${newversion}_prosilver.patch" />
<exec dir="build" escape="false"
@ -204,12 +204,6 @@
<phingcall target="checksum-dir">
<property name="dir" value="build/new_version/release_files" />
</phingcall>
<phingcall target="sign-packages">
<property name="dir" value="build/new_version/release_files" />
</phingcall>
<exec dir="build" command="php generate_package_json.php > new_version/packages.json"/>
</target>
<target name="checksum-dir">
@ -226,31 +220,6 @@
<exec dir="${dir}" command="sha256sum ${filename} > ${filename}.sha256" />
</target>
<target name="sign-packages">
<property name="packageSignatureExists" value="false" />
<exec command="if [ -f 'build/package_signature' ]; then echo 'true'; else echo 'false'; fi;" outputProperty="packageSignatureExists" />
<if>
<equals arg1="${packageSignatureExists}" arg2="true" />
<then>
<foreach param="filename" absparam="absfilename" target="sign-file">
<fileset dir="${dir}">
<type type="file" />
<include name="*.tar.bz2"/>
<include name="*.zip"/>
</fileset>
</foreach>
</then>
<else>
<echo msg="Skipping signing of packages due to missing build/package_signature"/>
</else>
</if>
</target>
<target name="sign-file">
<echo msg="Creating signature file for ${absfilename}" />
<exec command="php build/generate_signature.php `cat build/package_signature` ${absfilename}" />
</target>
<target name="announcement" depends="prepare">
<echo msg="Writing download links and checksums for email announcement to save/announcement_email_${newversion}.txt" />
<exec dir="build" escape="false"

View file

@ -29,7 +29,7 @@ else
{
$fixVersion = $_SERVER['argv'][1];
$query = 'project IN (PHPBB, PHPBB3, SECURITY)
$query = 'project IN (PHPBB3, SECURITY)
AND resolution = Fixed
AND fixVersion = "' . $fixVersion . '"
AND status IN ("Unverified Fix", Closed)';

View file

@ -50,7 +50,7 @@ class build_package
);
$this->package_infos = array(
'package_name' => 'phpBB',
'package_name' => 'phpBB3',
'name_prefix' => 'phpbb',
'simple_name' => 'release-' . $_latest,
'new_version_number' => $_latest,

View file

@ -1,116 +0,0 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\Sniffs\CodeLayout;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
/**
* Checks that union type declarations follows the coding guidelines.
*/
class UnionTypesCheckSniff implements Sniff
{
/**
* {@inheritdoc}
*/
public function register()
{
return [
T_FUNCTION,
T_CLASS,
];
}
/**
* {@inheritdoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
if ($tokens[$stackPtr]['type'] === 'T_FUNCTION')
{
$method_params = $phpcsFile->getMethodParameters($stackPtr);
$method_params_array = array_column($method_params, 'type_hint', 'token');
foreach ($method_params_array as $stack_pointer => $type_hint)
{
$this->check_union_type($phpcsFile, $stack_pointer, $type_hint);
}
$method_properties = $phpcsFile->getMethodProperties($stackPtr);
$this->check_union_type($phpcsFile, $stackPtr, $method_properties['return_type']);
}
else if ($tokens[$stackPtr]['type'] === 'T_CLASS')
{
$class_token = $tokens[$stackPtr];
$class_closer_pointer = $class_token['scope_closer'];
$first_method_pointer = $phpcsFile->findNext(T_FUNCTION, $stackPtr);
$class_members_declarations_end_pointer = $first_method_pointer ?: $class_closer_pointer;
$stack_pointer = $stackPtr;
while(($class_member_pointer = $phpcsFile->findNext(T_VARIABLE, $stack_pointer)) !== false && ($class_member_pointer < $class_members_declarations_end_pointer))
{
$properties = $phpcsFile->getMemberProperties($class_member_pointer);
$this->check_union_type($phpcsFile, $class_member_pointer, $properties['type']);
$stack_pointer = $class_member_pointer + 1;
}
}
}
public function check_union_type(File $phpcsFile, $stack_pointer, $type_hint)
{
if (empty($type_hint))
{
return;
}
if (!strpos($type_hint, '|') && $type_hint[0] == '?') // Check nullable shortcut syntax
{
$type = substr($type_hint, 1);
$error = 'Nullable shortcut syntax must not be used. Use union type instead: %1$s|null; found %2$s';
$data = [$type, $type_hint];
$phpcsFile->addError($error, $stack_pointer, 'ShortNullableSyntax', $data);
}
else if ((count($types_array = explode('|', $type_hint))) > 1) // Check union type layout
{
$types_array_null_less = $types_array;
// Check 'null' to be the last element
$null_position = array_search('null', $types_array);
if ($null_position !== false && $null_position != array_key_last($types_array))
{
$error = 'The "null" type hint must be the last of the union type elements; found %s';
$data = [implode('|', $types_array)];
$phpcsFile->addError($error, $stack_pointer, 'NullAlwaysLast', $data);
}
// Check types excepting 'null' to follow alphabetical order
if ($null_position !== false)
{
array_splice($types_array_null_less, $null_position, 1);
}
if (count($types_array_null_less) > 1)
{
$types_array_null_less_sorted = $types_array_null_less;
sort($types_array_null_less_sorted);
if (!empty(array_diff_assoc($types_array_null_less, $types_array_null_less_sorted)))
{
$error = 'Union type elements must be sorted alphabetically excepting the "null" type hint must be the last if any; found %s';
$data = [implode('|', $types_array)];
$phpcsFile->addError($error, $stack_pointer, 'AlphabeticalSort', $data);
}
}
}
}
}

View file

@ -11,8 +11,6 @@
*
*/
namespace phpbb\Sniffs\Commenting;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
@ -23,7 +21,7 @@ use PHP_CodeSniffer\Sniffs\Sniff;
* @package code_sniffer
* @author Manuel Pichler <mapi@phpundercontrol.org>
*/
class FileCommentSniff implements Sniff
class phpbb_Sniffs_Commenting_FileCommentSniff implements Sniff
{
/**
* Returns an array of tokens this test wants to listen for.

View file

@ -11,8 +11,6 @@
*
*/
namespace phpbb\Sniffs\ControlStructures;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
@ -20,7 +18,7 @@ use PHP_CodeSniffer\Sniffs\Sniff;
* Checks that the opening brace of a control structures is on the line after.
* From Generic_Sniffs_Functions_OpeningFunctionBraceBsdAllmanSniff
*/
class OpeningBraceBsdAllmanSniff implements Sniff
class phpbb_Sniffs_ControlStructures_OpeningBraceBsdAllmanSniff implements Sniff
{
/**
* Registers the tokens that this sniff wants to listen for.

View file

@ -10,7 +10,6 @@
* the docs/CREDITS.txt file.
*
*/
namespace phpbb\Sniffs\ControlStructures;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
@ -19,7 +18,7 @@ use PHP_CodeSniffer\Sniffs\Sniff;
* Checks that there is exactly one space between the keyword and the opening
* parenthesis of a control structures.
*/
class OpeningParenthesisSniff implements Sniff
class phpbb_Sniffs_ControlStructures_OpeningParenthesisSniff implements Sniff
{
/**
* Registers the tokens that this sniff wants to listen for.

View file

@ -11,8 +11,6 @@
*
*/
namespace phpbb\Sniffs\ControlStructures;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
@ -20,7 +18,7 @@ use PHP_CodeSniffer\Sniffs\Sniff;
* Checks that the visibility qualifiers are placed after the static keyword
* according to the coding guidelines
*/
class StaticKeywordSniff implements Sniff
class phpbb_Sniffs_ControlStructures_StaticKeywordSniff implements Sniff
{
/**
* Registers the tokens that this sniff wants to listen for.
@ -53,7 +51,7 @@ class StaticKeywordSniff implements Sniff
if (in_array($tokens[$stackPtr + 2]['code'], $disallowed_after_tokens))
{
$error = 'Access specifier (e.g. public) should not follow static scope attribute. Encountered "' . $tokens[$stackPtr + 2]['content'] . '" after static';
$phpcsFile->addError($error, $stackPtr, 'InvalidStaticFunctionDeclaration');
$phpcsFile->addWarning($error, $stackPtr, 'InvalidStaticFunctionDeclaration', [], 1);
}
}
}

View file

@ -11,15 +11,13 @@
*
*/
namespace phpbb\Sniffs\Namespaces;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
/**
* Checks that each use statement is used.
*/
class UnusedUseSniff implements Sniff
class phpbb_Sniffs_Namespaces_UnusedUseSniff implements Sniff
{
const FIND = [
T_NS_SEPARATOR,
@ -51,21 +49,10 @@ class UnusedUseSniff implements Sniff
$phpcsFile->addError($error, $stack_pointer, 'FullName');
}
/*
* Check for possible union types (like string|MyType|null)
* and question mark nullable type syntax (like ?MyType)
*/
$types = explode('|', $found_name);
foreach ($types as $type)
{
// Nullable type syntax
$type = (strpos($type, '?') === 0) ? substr($type, 1) : $type;
if ($short_name === $type)
if ($found_name === $short_name)
{
return true;
}
}
return false;
}
@ -195,7 +182,7 @@ class UnusedUseSniff implements Sniff
// Checks in type hinting
$old_function_declaration = $stackPtr;
while (($function_declaration = $phpcsFile->findNext([T_FUNCTION, T_CLOSURE], ($old_function_declaration + 1))) !== false)
while (($function_declaration = $phpcsFile->findNext(T_FUNCTION, ($old_function_declaration + 1))) !== false)
{
$old_function_declaration = $function_declaration;
@ -205,9 +192,6 @@ class UnusedUseSniff implements Sniff
{
$ok = $this->check($phpcsFile, $param['type_hint'], $class_name_full, $class_name_short, $function_declaration) || $ok;
}
$method_properties = $phpcsFile->getMethodProperties($function_declaration);
$ok = $this->check($phpcsFile, $method_properties['return_type'], $class_name_full, $class_name_short, $function_declaration) || $ok;
}
// Checks in catch blocks

View file

@ -17,6 +17,9 @@
<!-- There MUST not be more than one statement per line. -->
<rule ref="Generic.Formatting.DisallowMultipleStatements" />
<!-- Call-time pass-by-reference MUST not be used. -->
<rule ref="Generic.Functions.CallTimePassByReference.NotAllowed" />
<!-- Filenames MUST be lowercase. -->
<rule ref="Generic.Files.LowercasedFilename" />

View file

@ -45,8 +45,4 @@
<!-- There MUST NOT be unused use statements. -->
<rule ref="./phpbb/Sniffs/Namespaces/UnusedUseSniff.php" />
<!-- The null type SHALL be the last union type element, other types SHALL follow alphabetical order.
No nullable type shortcut syntax should be used. -->
<rule ref="./phpbb/Sniffs/CodeLayout/UnionTypesCheckSniff.php" />
</ruleset>

View file

@ -19,9 +19,9 @@ do
$command "$1.$ext"
for file in `find phpBB -name '.svn' -prune -o -type f -print`
for file in `find phpBB3 -name '.svn' -prune -o -type f -print`
do
orig_file="${file/#phpBB/$orig_dir}"
orig_file="${file/#phpBB3/$orig_dir}"
diff_result=`diff $orig_file $file`
if [ -n "$diff_result" ]
@ -31,7 +31,7 @@ do
fi
done
rm -rf phpBB
rm -rf phpBB3
done
cd ..

View file

@ -120,12 +120,6 @@ function phpbb_add_package_file(array &$package_list, $name, $file_name, $type,
$filedata->filesize = filesize($file_path);
$filedata->checksum = trim(preg_replace('/(^\w+)(.+)/', '$1', file_get_contents($file_path . '.sha256')));
$filedata->filetype = $extension;
if (file_exists($file_path . '.sig'))
{
$filedata->signature = trim(file_get_contents($file_path . '.sig'));
}
$package_file->files[] = $filedata;
}

View file

@ -1,52 +0,0 @@
#!/usr/bin/env php
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
if ($_SERVER['argc'] != 3)
{
echo "Please specify the secret key and filename for which the signature should be created, e.g. generate_signature.php mySecretSecret path/to/file\n";
exit(1);
}
$secret_key = base64_decode($_SERVER['argv'][1]);
$file_path = $_SERVER['argv'][2];
if (!extension_loaded('sodium'))
{
die('Required sodium extension not loaded');
}
if (!file_exists($file_path))
{
die('File does not exist');
}
$hash = hash_file('sha384', $file_path, true);
try
{
$signature = sodium_crypto_sign_detached($hash, $secret_key);
}
catch (SodiumException $e)
{
$keypair = sodium_crypto_sign_keypair();
$secret_key = base64_encode(sodium_crypto_sign_secretkey($keypair));
$public_key = base64_encode(sodium_crypto_sign_publickey($keypair));
echo 'Unable to create the signature: ' . $e->getMessage() . "\n";
echo "Maybe use these keys:\nPublic key: {$public_key}\nSecret key: {$secret_key}\n";
die();
}
$signature = base64_encode($signature);
file_put_contents($file_path . '.sig', $signature);

View file

@ -1,35 +0,0 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
class APCUIterator implements Iterator
{
public function current()
{
}
public function next()
{
}
public function key()
{
}
public function valid()
{
}
public function rewind()
{
}
}

View file

@ -1,15 +0,0 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
/** @link https://www.php.net/manual/en/image.constants.php */
define('IMG_COLOR_STYLED', -2);

View file

@ -1,16 +0,0 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
/** @link https://www.php.net/manual/en/ldap.constants.php */
define('LDAP_OPT_PROTOCOL_VERSION', 17);
define('LDAP_OPT_REFERRALS', 8);

View file

@ -1,20 +0,0 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
/** @link https://www.php.net/manual/en/memcached.constants.php */
class Memcached
{
public const OPT_COMPRESSION = -1001;
public const OPT_BINARY_PROTOCOL = 18;
}

View file

@ -1,19 +0,0 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
/** @link https://php.net/manual/en/oci8.constants.php */
define('OCI_DEFAULT', 0);
define('OCI_ASSOC', 1);
define('OCI_RETURN_NULLS', 4);

View file

@ -1,15 +0,0 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
/** @link https://www.php.net/manual/en/pgsql.constants.php */
define('PGSQL_CONNECT_FORCE_NEW', 2);

View file

@ -1,19 +0,0 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
/** @link https://phpredis.github.io/phpredis/Redis.html */
class Redis
{
public const OPT_PREFIX = 2;
public const SERIALIZER_PHP = 1;
}

View file

@ -1,33 +0,0 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
class SQLite3
{
public function query(string $query) {}
}
class SQLite3Result
{
public function fetchArray(int $mode = SQLITE3_BOTH) {}
}
/**
* @link https://www.php.net/manual/en/sqlite3.constants.php
*/
define('SQLITE3_ASSOC', 1);
define('SQLITE3_NUM', 2);
define('SQLITE3_BOTH', 3);
define('SQLITE3_OPEN_READONLY', 1);
define('SQLITE3_OPEN_READWRITE', 2);
define('SQLITE3_OPEN_CREATE', 4);

View file

@ -1,17 +0,0 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
/** @link https://www.php.net/manual/en/sqlsrv.constants.php */
define('SQLSRV_ERR_ERRORS', 0);
define('SQLSRV_FETCH_ASSOC', 2);
define('SQLSRV_CURSOR_STATIC', 'static');

View file

@ -1,55 +0,0 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
define('IN_PHPBB', true);
define('PHPBB_ENVIRONMENT', 'test');
$phpbb_root_path = 'phpBB/';
$phpEx = 'php';
global $table_prefix;
require_once $phpbb_root_path . 'includes/startup.php';
$table_prefix = 'phpbb_';
require_once $phpbb_root_path . 'includes/constants.php';
require_once $phpbb_root_path . 'phpbb/class_loader.' . $phpEx;
require_once $phpbb_root_path . 'includes/acp/acp_database.' . $phpEx;
require_once $phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx;
require_once $phpbb_root_path . 'includes/functions.' . $phpEx;
require_once $phpbb_root_path . 'includes/functions_acp.' . $phpEx;
require_once $phpbb_root_path . 'includes/functions_admin.' . $phpEx;
require_once $phpbb_root_path . 'includes/functions_compatibility.' . $phpEx;
require_once $phpbb_root_path . 'includes/functions_compress.' . $phpEx;
require_once $phpbb_root_path . 'includes/functions_content.' . $phpEx;
require_once $phpbb_root_path . 'includes/functions_display.' . $phpEx;
require_once $phpbb_root_path . 'includes/functions_mcp.' . $phpEx;
require_once $phpbb_root_path . 'includes/functions_module.' . $phpEx;
require_once $phpbb_root_path . 'includes/functions_posting.' . $phpEx;
require_once $phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx;
require_once $phpbb_root_path . 'includes/functions_transfer.' . $phpEx;
require_once $phpbb_root_path . 'includes/functions_user.' . $phpEx;
require_once $phpbb_root_path . 'includes/sphinxapi.' . $phpEx;
require_once $phpbb_root_path . 'includes/diff/diff.' . $phpEx;
require_once $phpbb_root_path . 'includes/diff/engine.' . $phpEx;
require_once $phpbb_root_path . 'includes/compatibility_globals.' . $phpEx;
$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', $phpbb_root_path . 'phpbb/', "php");
$phpbb_class_loader->register();
// Include files that require class loader to be initialized
require_once $phpbb_root_path . 'includes/acp/auth.' . $phpEx;
require_once $phpbb_root_path . 'includes/acp/acp_captcha.' . $phpEx;
class phpbb_cache_container extends \Symfony\Component\DependencyInjection\Container
{
}

View file

@ -1,56 +0,0 @@
#!/usr/bin/env php
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
if ($_SERVER['argc'] != 4)
{
echo "Please specify the public key, filename for which the signature should be check, and the signature file, e.g. verify_signature.php superPublicKey path/to/file path/to/signature\n";
exit(1);
}
$public_key = base64_decode($_SERVER['argv'][1]);
$file_path = $_SERVER['argv'][2];
$signature_path = $_SERVER['argv'][3];
if (!extension_loaded('sodium'))
{
die('Required sodium extension not loaded');
}
if (!file_exists($file_path))
{
die('File does not exist');
}
if (!file_exists($signature_path))
{
die('Signature file does not exist');
}
$hash = hash_file('sha384', $file_path, true);
$signature = base64_decode(file_get_contents($signature_path));
try
{
if (sodium_crypto_sign_verify_detached($signature, $hash, $public_key))
{
echo 'Signature is valid!';
}
else
{
echo 'Signature is not valid!';
}
} catch (SodiumException $e)
{
die('Unable to verify the signature: ' . $e->getMessage() . "\n");
}

Binary file not shown.

View file

@ -1,6 +1,6 @@
#!/bin/sh
#
# A hook to check syntax of a phpBB commit message, per:
# A hook to check syntax of a phpBB3 commit message, per:
# * <https://area51.phpbb.com/docs/dev/master/development/git.html>
# * <http://area51.phpbb.com/phpBB/viewtopic.php?p=209919#p209919>
#

View file

@ -56,7 +56,7 @@ catch (RuntimeException $e)
function work($pull_id, $remote)
{
// Get some basic data
$pull = get_pull('phpbb', 'phpbb', $pull_id);
$pull = get_pull('phpbb', 'phpbb3', $pull_id);
if (!$pull_id)
{
@ -79,7 +79,7 @@ function work($pull_id, $remote)
run("git checkout develop-olympus");
run("git pull $remote develop-olympus");
add_remote($pull_user, 'phpbb');
add_remote($pull_user, 'phpbb3');
run("git fetch $pull_user");
run("git merge --no-ff $pull_user/$pull_branch");
run("phpBB/vendor/bin/phpunit");
@ -94,7 +94,7 @@ function work($pull_id, $remote)
run("git checkout develop");
run("git pull $remote develop");
add_remote($pull_user, 'phpbb');
add_remote($pull_user, 'phpbb3');
run("git fetch $pull_user");
run("git merge --no-ff $pull_user/$pull_branch");
run("phpBB/vendor/bin/phpunit");

View file

@ -1,69 +0,0 @@
'use strict';
const gulp = require('gulp');
const rename = require('gulp-rename');
const concat = require('gulp-concat');
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const sorting = require('postcss-sorting');
const sortOrder = require('./.postcss-sorting.json');
// Config
const paths = {
styles: {
src: './phpBB/styles/prosilver/theme/*.css',
css: './phpBB/styles/prosilver/theme/',
},
};
function styles() {
return gulp.src(paths.styles.src, { sourcemaps: true })
.pipe(
postcss([
autoprefixer(),
sorting(sortOrder),
]),
)
.pipe(gulp.dest(paths.styles.css, { sourcemaps: './' }));
}
function minify() {
return gulp.src([
paths.styles.css + 'normalize.css',
paths.styles.css + 'base.css',
paths.styles.css + 'utilities.css',
paths.styles.css + 'icons.css',
paths.styles.css + 'common.css',
paths.styles.css + 'buttons.css',
paths.styles.css + 'links.css',
paths.styles.css + 'mentions.css',
paths.styles.css + 'content.css',
paths.styles.css + 'cp.css',
paths.styles.css + 'forms.css',
paths.styles.css + 'colours.css',
paths.styles.css + 'responsive.css',
paths.styles.css + 'bidi.css',
], { sourcemaps: true })
.pipe(concat('stylesheet.css'))
.pipe(
postcss([
cssnano(),
]),
)
.pipe(rename({
suffix: '.min',
extname: '.css',
}))
.pipe(gulp.dest(paths.styles.css, { sourcemaps: './' }));
}
function watch() {
gulp.watch(paths.styles.src, styles);
}
exports.style = styles;
exports.minify = minify;
exports.watch = watch;
exports.default = gulp.series(styles, minify, watch);

10469
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,116 +0,0 @@
{
"name": "phpbb",
"version": "4.0.0-dev",
"description": "phpBB Forum Software application",
"main": " ",
"directories": {
"doc": "docs"
},
"eslintConfig": {
"extends": "xo",
"ignorePatterns": [
"phpBB/adm/style/admin.js",
"phpBB/adm/style/ajax.js",
"phpBB/adm/style/permissions.js",
"phpBB/adm/style/tooltip.js",
"phpBB/assets/javascript/core.js",
"phpBB/assets/javascript/cropper.js",
"phpBB/assets/javascript/editor.js",
"phpBB/assets/javascript/hermite.js",
"phpBB/assets/javascript/installer.js",
"phpBB/assets/javascript/jquery-cropper.js",
"phpBB/assets/javascript/plupload.js",
"phpBB/ext/**/*.js",
"phpBB/styles/prosilver/template/ajax.js",
"phpBB/styles/prosilver/template/forum_fn.js",
"phpBB/**/*.min.js",
"phpBB/vendor/**/*.js",
"phpBB/vendor-ext/**/*.js",
"phpBB/phpbb/**/*.js",
"phpBB/tests/**/*.js"
],
"rules": {
"quotes": [
"error",
"single"
],
"comma-dangle": [
"error",
"always-multiline"
],
"block-spacing": "error",
"array-bracket-spacing": [
"error",
"always"
],
"multiline-comment-style": "off",
"computed-property-spacing": "off",
"space-before-function-paren": [
"error",
"never"
],
"space-in-parens": "off",
"capitalized-comments": "off",
"object-curly-spacing": [
"error",
"always"
],
"no-lonely-if": "off",
"unicorn/prefer-module": "off"
},
"env": {
"es6": true,
"browser": true,
"node": true,
"jquery": true
}
},
"browserslist": [
"> 1%",
"not ie 11",
"not samsung 10.1",
"not and_uc 12.12",
"not op_mini all",
"edge >= 18",
"ff >= 72",
"chrome >= 79",
"safari >= 13",
"ios >= 12.4"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/phpbb/phpbb.git"
},
"keywords": [
"phpBB",
"phpbb",
"forum",
"php",
"software",
"community"
],
"author": "",
"license": "GPL-2.0",
"bugs": {
"url": "https://tracker.phpbb.com"
},
"homepage": "https://www.phpbb.com",
"devDependencies": {
"autoprefixer": "^10.4.4",
"cssnano": "^5.1.7",
"eslint": "^8.13.0",
"eslint-config-xo": "^0.40.0",
"gulp": "^5.0.0",
"gulp-concat": "^2.6.1",
"gulp-postcss": "^9.0.1",
"gulp-rename": "^2.0.0",
"postcss": "^8.4.31",
"postcss-sorting": "^7.0.1",
"stylelint": "^14.7.0",
"stylelint-order": "^5.0.0",
"web-push-testing": "^1.1.1"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 826 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View file

@ -15,6 +15,7 @@
*/
define('IN_PHPBB', true);
define('ADMIN_START', true);
define('NEED_SID', true);
// Include files
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../';
@ -53,20 +54,12 @@ $module_id = $request->variable('i', '');
$mode = $request->variable('mode', '');
// Set custom style for admin area
/** @var \phpbb\template\base $template */
$template->set_custom_style(
[
[
$template->set_custom_style(array(
array(
'name' => 'adm',
'ext_path' => 'adm/style/',
]
],
[
$phpbb_admin_path . 'style',
$phpbb_root_path . 'styles/all/imgs/',
$phpbb_root_path . 'styles/all/template/',
],
);
),
), $phpbb_admin_path . 'style');
$template->assign_var('T_ASSETS_PATH', $phpbb_path_helper->update_web_root_path($phpbb_root_path . 'assets'));
$template->assign_var('T_TEMPLATE_PATH', $phpbb_path_helper->update_web_root_path($phpbb_root_path . 'style'));

View file

@ -49,13 +49,7 @@
<dl>
<dt><label for="{options.KEY}">{options.TITLE}{L_COLON}</label><!-- IF options.S_EXPLAIN --><br /><span>{options.TITLE_EXPLAIN}</span><!-- ENDIF --></dt>
<dd>
{% if options.CONTENT is iterable %}
{{ FormsBuildTemplate(options.CONTENT)}}
{% else %}
{options.CONTENT}
{% endif %}
</dd>
<dd>{options.CONTENT}</dd>
{% if (options.KEY == 'allow_attachments' and S_EMPTY_POST_GROUPS) or (options.KEY == 'allow_pm_attach' and S_EMPTY_PM_GROUPS) %}
<dd><span class="error">{{ lang(options.KEY == 'allow_attachments' ? 'NO_EXT_GROUP_ALLOWED_POST' : 'NO_EXT_GROUP_ALLOWED_PM', U_EXTENSION_GROUPS) }}</span></dd>
{% endif %}
@ -181,14 +175,8 @@
<dd><input type="text" id="group_name" size="20" maxlength="100" name="group_name" value="{GROUP_NAME}" /></dd>
</dl>
<dl>
<dt><label for="{{ S_CATEGORY_SELECT.id }}">{L_SPECIAL_CATEGORY}{L_COLON}</label><br /><span>{L_SPECIAL_CATEGORY_EXPLAIN}</span></dt>
<dd>
<select name="{{ S_CATEGORY_SELECT.name }}" id="{{ S_CATEGORY_SELECT.id }}">
{% for option in S_CATEGORY_SELECT.options %}
<option value="{{ option.value }}"{% if option.selected %} selected="selected"{% endif %}>{{ option.label }}</option>
{% endfor %}
</select>
</dd>
<dt><label for="category">{L_SPECIAL_CATEGORY}{L_COLON}</label><br /><span>{L_SPECIAL_CATEGORY_EXPLAIN}</span></dt>
<dd>{S_CATEGORY_SELECT}</dd>
</dl>
<dl>
<dt><label for="allowed">{L_ALLOWED}{L_COLON}</label></dt>
@ -207,10 +195,7 @@
</dl>
<dl>
<dt><label for="extgroup_filesize">{L_MAX_EXTGROUP_FILESIZE}{L_COLON}</label></dt>
<dd>
<input type="number" id="extgroup_filesize" min="0" max="999999999999999" step="any" name="max_filesize" value="{EXTGROUP_FILESIZE}" />
{{ FormsSelect(EXT_GROUP_SIZE_OPTIONS) }}
</dd>
<dd><input type="number" id="extgroup_filesize" min="0" max="999999999999999" step="any" name="max_filesize" value="{EXTGROUP_FILESIZE}" /> <select name="size_select">{S_EXT_GROUP_SIZE_OPTIONS}</select></dd>
</dl>
<dl>
<dt><label for="assigned_extensions">{L_ASSIGNED_EXTENSIONS}{L_COLON}</label></dt>
@ -290,14 +275,8 @@
<dd><input type="text" id="add_extension" size="20" maxlength="100" name="add_extension" value="{ADD_EXTENSION}" /></dd>
</dl>
<dl>
<dt><label for="{{ GROUP_SELECT_OPTIONS.id }}">{L_EXTENSION_GROUP}</label></dt>
<dd>
<select name="{{ GROUP_SELECT_OPTIONS.name }}" id="{{ GROUP_SELECT_OPTIONS.id }}">
{% for option in GROUP_SELECT_OPTIONS.options %}
<option value="{{ option.value }}"{% if option.selected %} selected="selected"{% endif %}>{{ option.label }}</option>
{% endfor %}
</select>
</dd>
<dt><label for="extension_group">{L_EXTENSION_GROUP}</label></dt>
<dd>{GROUP_SELECT_OPTIONS}</dd>
</dl>
<p class="quick">
@ -330,13 +309,7 @@
<!-- ENDIF -->
<tr>
<td><strong>{extensions.EXTENSION}</strong></td>
<td>
<select name="{{ extensions.GROUP_OPTIONS.name }}" id="{{ extensions.GROUP_OPTIONS.id }}">
{% for option in extensions.GROUP_OPTIONS.options %}
<option value="{{ option.value }}"{% if option.selected %} selected="selected"{% endif %}>{{ option.label }}</option>
{% endfor %}
</select>
</td>
<td>{extensions.GROUP_OPTIONS}</td>
<td><input type="checkbox" class="radio" name="extension_id_list[]" value="{extensions.EXTENSION_ID}" /><input type="hidden" name="extension_change_list[]" value="{extensions.EXTENSION_ID}" /></td>
</tr>
<!-- END extensions -->

View file

@ -0,0 +1,11 @@
<dl>
<dt><label for="avatar_remote_url">{L_LINK_REMOTE_AVATAR}{L_COLON}</label><br /><span>{L_LINK_REMOTE_AVATAR_EXPLAIN}</span></dt>
<dd><input type="url" name="avatar_remote_url" id="avatar_remote_url" value="{AVATAR_REMOTE_URL}" class="inputbox" /></dd>
</dl>
<dl>
<dt><label for="avatar_remote_width">{L_LINK_REMOTE_SIZE}{L_COLON}</label><br /><span>{L_LINK_REMOTE_SIZE_EXPLAIN}</span></dt>
<dd>
<input type="number" name="avatar_remote_width" id="avatar_remote_width" min="{AVATAR_MIN_WIDTH}" max="{AVATAR_MAX_WIDTH}" value="{AVATAR_REMOTE_WIDTH}" class="inputbox autowidth" /> {L_PIXEL} &times;&nbsp;
<input type="number" name="avatar_remote_height" id="avatar_remote_height" min="{AVATAR_MIN_HEIGHT}" max="{AVATAR_MAX_HEIGHT}" value="{AVATAR_REMOTE_HEIGHT}" class="inputbox autowidth" /> {L_PIXEL}
</dd>
</dl>

View file

@ -3,67 +3,9 @@
<dd><input type="hidden" name="MAX_FILE_SIZE" value="{AVATAR_UPLOAD_SIZE}" /><input type="file" name="avatar_upload_file" id="avatar_upload_file" class="inputbox autowidth" accept="{{ AVATAR_ALLOWED_EXTENSIONS }}" /></dd>
</dl>
{% INCLUDECSS T_ASSETS_PATH ~ '/css/cropper.min.css' %}
{% INCLUDEJS T_ASSETS_PATH ~ '/javascript/cropper.min.js' %}
{% INCLUDEJS T_ASSETS_PATH ~ '/javascript/jquery-cropper.js' %}
{% INCLUDEJS T_ASSETS_PATH ~ '/javascript/phpbb-avatars.js' %}
<input type="hidden" id="avatar-cropper-data" name="avatar_cropper_data" value=""
data-min-width="{{ AVATAR_MIN_WIDTH }}" data-max-width="{{ AVATAR_MAX_WIDTH }}"
data-min-height="{{ AVATAR_MIN_HEIGHT }}" data-max-height="{{ AVATAR_MAX_HEIGHT }}"
/>
{% apply spaceless %}
<div class="avatar-cropper-buttons" id="avatar-cropper-buttons">
<div class="button-group">
<button class="button" type="button" title="{{ lang('ZOOM_IN') }}" data-cropper-action="zoom,0.1">
{{ Icon('font', 'search-plus', '', true) }}
</button>
<button class="button" type="button" title="{{ lang('ZOOM_OUT') }}" data-cropper-action="zoom,-0.1">
{{ Icon('font', 'search-minus', '', true) }}
</button>
</div>
<div class="button-group">
<button class="button" type="button" title="{{ lang('MOVE_LEFT') }}" data-cropper-action="move,-10,0">
{{ Icon('font', 'arrow-left', '', true) }}
</button>
<button class="button" type="button" title="{{ lang('MOVE_RIGHT') }}" data-cropper-action="move,10,0">
{{ Icon('font', 'arrow-right', '', true) }}
</button>
<button class="button" type="button" title="{{ lang('MOVE_UP') }}" data-cropper-action="move,0,-10">
{{ Icon('font', 'arrow-up', '', true) }}
</button>
<button class="button" type="button" title="{{ lang('MOVE_DOWN') }}" data-cropper-action="move,0,10">
{{ Icon('font', 'arrow-down', '', true) }}
</button>
</div>
<div class="button-group">
<button class="button" type="button" title="{{ lang('ROTATE_LEFT') }}" data-cropper-action="rotate,-90">
{{ Icon('font', 'rotate-left', '', true) }}
</button>
<button class="button" type="button" title="{{ lang('ROTATE_RIGHT') }}" data-cropper-action="rotate,90">
{{ Icon('font', 'rotate-right', '', true) }}
</button>
</div>
<div class="button-group">
<button class="button" type="button" title="{{ lang('FLIP_HORIZONTALLY') }}" data-cropper-action="scaleX">
{{ Icon('font', 'arrows-left-right', '', true) }}
</button>
<button class="button" type="button" title="{{ lang('FLIP_VERTICALLY') }}" data-cropper-action="scaleY">
{{ Icon('font', 'arrows-up-down', '', true) }}
</button>
</div>
<div class="button-group">
<button class="button" type="button" title="{{ lang('RESET') }}" data-cropper-action="reset">
{{ Icon('font', 'arrows-rotate', '', true) }}
</button>
<button class="button" type="button" title="{{ lang('CLEAR') }}" data-cropper-action="clear">
{{ Icon('font', 'xmark', '', true) }}
</button>
</div>
</div>
{% endapply %}
<!-- IF S_UPLOAD_AVATAR_URL -->
<dl>
<dt><label for="avatar_upload_url">{L_UPLOAD_AVATAR_URL}{L_COLON}</label><br /><span>{L_UPLOAD_AVATAR_URL_EXPLAIN}</span></dt>
<dd><input type="url" name="avatar_upload_url" id="avatar_upload_url" value="" class="inputbox" /></dd>
</dl>
<!-- ENDIF -->

View file

@ -11,11 +11,11 @@
<script>
// <![CDATA[
const ban_length = [];
var ban_length = new Array();
ban_length[-1] = '';
const ban_reason = [];
var ban_reason = new Array();
ban_reason[-1] = '';
const ban_give_reason = [];
var ban_give_reason = new Array();
ban_give_reason[-1] = '';
<!-- BEGIN bans -->
@ -43,19 +43,6 @@
}
}
document.addEventListener("DOMContentLoaded", () => {
const $unbanSelect = document.getElementById('unban');
if ($unbanSelect) {
$unbanSelect.addEventListener('change', function () {
if (this.selectedIndex > -1) {
display_details(this.options[this.selectedIndex].value);
} else {
display_details(-1);
}
});
}
});
// ]]>
</script>
@ -73,6 +60,11 @@
<dd><label for="banlength"><select name="banlength" id="banlength" onchange="if(this.value==-1){document.getElementById('banlengthother').style.display = 'block';}else{document.getElementById('banlengthother').style.display='none';}">{S_BAN_END_OPTIONS}</select></label></dd>
<dd id="banlengthother" style="display: none;"><label><input type="text" name="banlengthother" class="inputbox" /><br /><span>{L_YEAR_MONTH_DAY}</span></label></dd>
</dl>
<dl>
<dt><label for="banexclude">{L_BAN_EXCLUDE}{L_COLON}</label><br /><span>{L_BAN_EXCLUDE_EXPLAIN}</span></dt>
<dd><label><input type="radio" name="banexclude" value="1" class="radio" /> {L_YES}</label>
<label><input type="radio" name="banexclude" id="banexclude" value="0" checked="checked" class="radio" /> {L_NO}</label></dd>
</dl>
<dl>
<dt><label for="banreason">{L_BAN_REASON}{L_COLON}</label></dt>
<dd><input name="banreason" type="text" class="text medium" maxlength="255" id="banreason" /></dd>
@ -98,41 +90,44 @@
<p>{L_UNBAN_EXPLAIN}</p>
<form id="acp_unban" method="post" action="{{ U_ACTION }}">
<form id="acp_unban" method="post" action="{U_ACTION}">
<fieldset>
<legend>{{ lang('UNBAN_TITLE') }}</legend>
<legend>{L_UNBAN_TITLE}</legend>
{% if BANNED_SELECT %}
<!-- IF S_BANNED_OPTIONS -->
<dl>
<dt><label for="unban">{{ lang('BAN_CELL') ~ lang('COLON') }}</label></dt>
<dd>
{{ FormsSelect(BANNED_SELECT) }}
</dd>
<dt><label for="unban">{L_BAN_CELL}{L_COLON}</label></dt>
<dd><select id="unban" name="unban[]" multiple="multiple" size="10" style="width: 50%" onchange="if (this.selectedIndex > -1) display_details(this.options[this.selectedIndex].value); else display_details(-1);">{BANNED_OPTIONS}</select></dd>
</dl>
<dl>
<dt><label for="unbanlength">{{ lang('BAN_LENGTH') ~ lang('COLON') }}</label></dt>
<dt><label for="unbanlength">{L_BAN_LENGTH}{L_COLON}</label></dt>
<dd><input style="border: 0;" type="text" class="text full" readonly="readonly" name="unbanlength" id="unbanlength" /></dd>
</dl>
<dl>
<dt><label for="unbanreason">{{ lang('BAN_REASON') ~ lang('COLON') }}</label></dt>
<dt><label for="unbanreason">{L_BAN_REASON}{L_COLON}</label></dt>
<dd><textarea style="border: 0;" class="text full" readonly="readonly" name="unbanreason" id="unbanreason" rows="5" cols="80">&nbsp;</textarea></dd>
</dl>
<dl>
<dt><label for="unbangivereason">{{ lang('BAN_GIVE_REASON') ~ lang('COLON') }}</label></dt>
<dt><label for="unbangivereason">{L_BAN_GIVE_REASON}{L_COLON}</label></dt>
<dd><textarea style="border: 0;" class="text full" readonly="readonly" name="unbangivereason" id="unbangivereason" rows="5" cols="80">&nbsp;</textarea></dd>
</dl>
<p class="submit-buttons">
<input class="button1" type="submit" id="unbansubmit" name="unbansubmit" value="{{ lang('SUBMIT') }}" />&nbsp;
<input class="button2" type="reset" id="unbanreset" name="unbanreset" value="{{ lang('RESET') }}" />
<input class="button1" type="submit" id="unbansubmit" name="unbansubmit" value="{L_SUBMIT}" />&nbsp;
<input class="button2" type="reset" id="unbanreset" name="unbanreset" value="{L_RESET}" />
</p>
{% else %}
<p>{{ lang('NO_BAN_CELL') }}</p>
{% endif %}
{{ S_FORM_TOKEN }}
{S_FORM_TOKEN}
</fieldset>
<!-- ELSE -->
<p>{L_NO_BAN_CELL}</p>
{S_FORM_TOKEN}
</fieldset>
<!-- ENDIF -->
</form>
<!-- INCLUDE overall_footer.html -->

View file

@ -14,7 +14,7 @@
<fieldset>
<legend>{L_BBCODE_USAGE}</legend>
<p>{{ lang('BBCODE_USAGE_EXPLAIN', '<a href="#down">', '</a>') }}</p>
<p>{L_BBCODE_USAGE_EXPLAIN}</p>
<dl>
<dt><label for="bbcode_match">{L_EXAMPLES}</label><br /><br /><span>{L_BBCODE_USAGE_EXAMPLE}</span></dt>
<dd><textarea id="bbcode_match" name="bbcode_match" cols="60" rows="5">{BBCODE_MATCH}</textarea></dd>
@ -47,17 +47,6 @@
</dl>
</fieldset>
<fieldset>
<legend>{{ lang('APPEARANCE') }}</legend>
<dl>
<dt><label for="bbcode_font_icon">{{ lang('BBCODE_FONT_ICON') }}</label><br><span>{{ lang('BBCODE_FONT_ICON_EXPLAIN', '<a href="https://fontawesome.com/v6/icons/" target="_blank">', '</a>') }}</span></dt>
<dd>
<input type="text" name="bbcode_font_icon" id="bbcode_font_icon" value="{{ BBCODE_FONT_ICON }}" />
{{ Icon('font', ' ', '', false, '', {'id':'bbcode_icon_preview'}) }}
</dd>
</dl>
</fieldset>
<!-- EVENT acp_bbcodes_edit_fieldsets_after -->
<fieldset class="submit-buttons">

View file

@ -27,13 +27,7 @@
<dl>
<dt><label for="{options.KEY}">{options.TITLE}{L_COLON}</label><!-- IF options.S_EXPLAIN --><br /><span>{options.TITLE_EXPLAIN}</span><!-- ENDIF --></dt>
<dd>
{% if options.CONTENT is iterable %}
{{ FormsBuildTemplate(options.CONTENT)}}
{% else %}
{{ options.CONTENT }}
{% endif %}
</dd>
<dd>{options.CONTENT}</dd>
</dl>
<!-- ENDIF -->

View file

@ -27,21 +27,15 @@
</dl>
<dl>
<dt><label for="bot_style">{L_BOT_STYLE}{L_COLON}</label><br /><span>{L_BOT_STYLE_EXPLAIN}</span></dt>
<dd>
{{ FormsSelect(S_STYLE_OPTIONS) }}
</dd>
<dd><select id="bot_style" name="bot_style">{S_STYLE_OPTIONS}</select></dd>
</dl>
<dl>
<dt><label for="{{ LANG_OPTIONS.id }}">{L_BOT_LANG}{L_COLON}</label><br /><span>{L_BOT_LANG_EXPLAIN}</span></dt>
<dd>
{{ FormsSelect(LANG_OPTIONS) }}
</dd>
<dt><label for="bot_lang">{L_BOT_LANG}{L_COLON}</label><br /><span>{L_BOT_LANG_EXPLAIN}</span></dt>
<dd><select id="bot_lang" name="bot_lang">{S_LANG_OPTIONS}</select></dd>
</dl>
<dl>
<dt><label for="bot_active">{L_BOT_ACTIVE}{L_COLON}</label></dt>
<dd>
{{ FormsSelect(S_ACTIVE_OPTIONS) }}
</dd>
<dd><select id="bot_active" name="bot_active">{S_ACTIVE_OPTIONS}</select></dd>
</dl>
<dl>
<dt><label for="bot_agent">{L_BOT_AGENT}{L_COLON}</label><br /><span>{L_BOT_AGENT_EXPLAIN}</span></dt>

View file

@ -1,85 +1,79 @@
{% include 'overall_header.html' %}
<!-- INCLUDE overall_header.html -->
<a id="maincontent"></a>
<h1>{{ lang('ACP_VC_SETTINGS') }}</h1>
<h1>{L_ACP_VC_SETTINGS}</h1>
<p>{{ lang('ACP_VC_SETTINGS_EXPLAIN') }}</p>
<p>{L_ACP_VC_SETTINGS_EXPLAIN}</p>
<p>{{ lang('ACP_VC_EXT_GET_MORE') }}</p>
<p>{L_ACP_VC_EXT_GET_MORE}</p>
{% if ERRORS %}
<!-- IF ERROR_MSG -->
<div class="errorbox">
<h3>{{ lang('WARNING') }}</h3>
<p>{{ ERRORS|join('<br>') }}</p>
<h3>{L_WARNING}</h3>
<p>{ERROR_MSG}</p>
</div>
{% endif %}
<!-- ENDIF -->
<form id="acp_captcha" method="post" action="{{ U_ACTION }}">
<form id="acp_captcha" method="post" action="{U_ACTION}">
<fieldset>
<legend>{{ lang('GENERAL_OPTIONS') }}</legend>
<legend>{L_GENERAL_OPTIONS}</legend>
<dl>
<dt><label for="enable_confirm">{{ lang('VISUAL_CONFIRM_REG') ~ lang('COLON') }}</label><br /><span>{{ lang('VISUAL_CONFIRM_REG_EXPLAIN') }}</span></dt>
<dd>
<label><input type="radio" class="radio" id="enable_confirm" name="enable_confirm" value="1"{% if REG_ENABLE %} checked="checked"{% endif %}/> {{ lang('ENABLED') }}</label>
<label><input type="radio" class="radio" name="enable_confirm" value="0"{% if not REG_ENABLE %} checked="checked"{% endif %}/> {{ lang('DISABLED') }}</label>
</dd>
<dt><label for="enable_confirm">{L_VISUAL_CONFIRM_REG}{L_COLON}</label><br /><span>{L_VISUAL_CONFIRM_REG_EXPLAIN}</span></dt>
<dd><label><input type="radio" class="radio" id="enable_confirm" name="enable_confirm" value="1"<!-- IF REG_ENABLE --> checked="checked"<!-- ENDIF --> /> {L_ENABLED}</label>
<label><input type="radio" class="radio" name="enable_confirm" value="0"<!-- IF not REG_ENABLE --> checked="checked"<!-- ENDIF --> /> {L_DISABLED}</label></dd>
</dl>
<dl>
<dt><label for="max_reg_attempts">{{ lang('REG_LIMIT') ~ lang('COLON') }}</label><br /><span>{{ lang('REG_LIMIT_EXPLAIN') }}</span></dt>
<dd><input id="max_reg_attempts" type="number" min="0" max="9999" name="max_reg_attempts" value="{{ REG_LIMIT }}" /></dd>
<dt><label for="max_reg_attempts">{L_REG_LIMIT}{L_COLON}</label><br /><span>{L_REG_LIMIT_EXPLAIN}</span></dt>
<dd><input id="max_reg_attempts" type="number" min="0" max="9999" name="max_reg_attempts" value="{REG_LIMIT}" /></dd>
</dl>
<dl>
<dt><label for="max_login_attempts">{{ lang('MAX_LOGIN_ATTEMPTS') ~ lang('COLON') }}</label><br /><span>{{ lang('MAX_LOGIN_ATTEMPTS_EXPLAIN') }}</span></dt>
<dd><input id="max_login_attempts" type="number" min="0" max="9999" name="max_login_attempts" value="{{ MAX_LOGIN_ATTEMPTS }}" /></dd>
<dt><label for="max_login_attempts">{L_MAX_LOGIN_ATTEMPTS}{L_COLON}</label><br /><span>{L_MAX_LOGIN_ATTEMPTS_EXPLAIN}</span></dt>
<dd><input id="max_login_attempts" type="number" min="0" max="9999" name="max_login_attempts" value="{MAX_LOGIN_ATTEMPTS}" /></dd>
</dl>
<dl>
<dt><label for="enable_post_confirm">{{ lang('VISUAL_CONFIRM_POST') ~ lang('COLON') }}</label><br /><span>{{ lang('VISUAL_CONFIRM_POST_EXPLAIN') }}</span></dt>
<dd>
<label><input type="radio" class="radio" id="enable_post_confirm" name="enable_post_confirm" value="1"{% if POST_ENABLE %} checked="checked"{% endif %}/> {{ lang('ENABLED') }}</label>
<label><input type="radio" class="radio" name="enable_post_confirm" value="0"{% if not POST_ENABLE %} checked="checked"{% endif %}/> {{ lang('DISABLED') }}</label>
</dd>
<dt><label for="enable_post_confirm">{L_VISUAL_CONFIRM_POST}{L_COLON}</label><br /><span>{L_VISUAL_CONFIRM_POST_EXPLAIN}</span></dt>
<dd><label><input type="radio" class="radio" id="enable_post_confirm" name="enable_post_confirm" value="1"<!-- IF POST_ENABLE --> checked="checked"<!-- ENDIF --> /> {L_ENABLED}</label>
<label><input type="radio" class="radio" name="enable_post_confirm" value="0"<!-- IF not POST_ENABLE --> checked="checked"<!-- ENDIF --> /> {L_DISABLED}</label></dd>
</dl>
<dl>
<dt><label for="confirm_refresh">{{ lang('VISUAL_CONFIRM_REFRESH') ~ lang('COLON') }}</label><br /><span>{{ lang('VISUAL_CONFIRM_REFRESH_EXPLAIN') }}</span></dt>
<dd>
<label><input type="radio" class="radio" id="confirm_refresh" name="confirm_refresh" value="1"{% if CONFIRM_REFRESH %} checked="checked"{% endif %}/> {{ lang('ENABLED') }}</label>
<label><input type="radio" class="radio" name="confirm_refresh" value="0"{% if not CONFIRM_REFRESH %} checked="checked"{% endif %}/> {{ lang('DISABLED') }}</label>
</dd>
<dt><label for="confirm_refresh">{L_VISUAL_CONFIRM_REFRESH}{L_COLON}</label><br /><span>{L_VISUAL_CONFIRM_REFRESH_EXPLAIN}</span></dt>
<dd><label><input type="radio" class="radio" id="confirm_refresh" name="confirm_refresh" value="1"<!-- IF CONFIRM_REFRESH --> checked="checked"<!-- ENDIF --> /> {L_ENABLED}</label>
<label><input type="radio" class="radio" name="confirm_refresh" value="0"<!-- IF not CONFIRM_REFRESH --> checked="checked"<!-- ENDIF --> /> {L_DISABLED}</label></dd>
</dl>
</fieldset>
<fieldset>
<legend>{{ lang('AVAILABLE_CAPTCHAS') }}</legend>
<legend>{L_AVAILABLE_CAPTCHAS}</legend>
<dl>
<dt><label for="captcha_select">{{ lang('CAPTCHA_SELECT') ~ lang('COLON') }}</label><br><span>{{ lang('CAPTCHA_SELECT_EXPLAIN') }}</span></dt>
<dd>{{ FormsSelect(CAPTCHA_SELECT | merge({id: 'captcha_select', onchange: "(document.getElementById('acp_captcha')).submit()"})) }}</dd>
<dt><label for="captcha_select">{L_CAPTCHA_SELECT}{L_COLON}</label><br /><span>{L_CAPTCHA_SELECT_EXPLAIN}</span></dt>
<dd><select id="captcha_select" name="select_captcha" onchange="(document.getElementById('acp_captcha')).submit()" >{CAPTCHA_SELECT}</select></dd>
</dl>
{% if S_CAPTCHA_HAS_CONFIG %}
<!-- IF S_CAPTCHA_HAS_CONFIG -->
<dl>
<dt><label for="configure">{{ lang('CAPTCHA_CONFIGURE') ~ lang('COLON') }}</label><br /><span>{{ lang('CAPTCHA_CONFIGURE_EXPLAIN') }}</span></dt>
<dd><input class="button2" type="submit" id="configure" name="configure" value="{{ lang('CONFIGURE') }}" /></dd>
<dt><label for="configure">{L_CAPTCHA_CONFIGURE}{L_COLON}</label><br /><span>{L_CAPTCHA_CONFIGURE_EXPLAIN}</span></dt>
<dd><input class="button2" type="submit" id="configure" name="configure" value="{L_CONFIGURE}" /></dd>
</dl>
{% endif %}
<!-- ENDIF -->
</fieldset>
{% if CAPTCHA_PREVIEW_TPL %}
<!-- IF CAPTCHA_PREVIEW_TPL -->
<fieldset>
<legend>{{ lang('PREVIEW') }}</legend>
{% include CAPTCHA_PREVIEW_TPL %}
<legend>{L_PREVIEW}</legend>
<!-- INCLUDE {CAPTCHA_PREVIEW_TPL} -->
</fieldset>
{% endif %}
<!-- ENDIF -->
<fieldset>
<legend>{{ lang('ACP_SUBMIT_CHANGES') }}</legend>
<legend>{L_ACP_SUBMIT_CHANGES}</legend>
<p class="submit-buttons">
<input class="button1" type="submit" id="main_submit" name="main_submit" value="{{ lang('SUBMIT') }}" />&nbsp;
<input class="button2" type="reset" id="form_reset" name="reset" value="{{ lang('RESET') }}" />&nbsp;
<input class="button1" type="submit" id="main_submit" name="main_submit" value="{L_SUBMIT}" />&nbsp;
<input class="button2" type="reset" id="form_reset" name="reset" value="{L_RESET}" />&nbsp;
</p>
{{ S_FORM_TOKEN }}
{S_FORM_TOKEN}
</fieldset>
</form>
{% include 'overall_footer.html' %}
<!-- INCLUDE overall_footer.html -->

View file

@ -62,7 +62,7 @@
<label><input type="checkbox" class="radio" name="disable_magic_url"<!-- IF S_MAGIC_URL_DISABLE_CHECKED --> checked="checked"<!-- ENDIF --> /> {L_DISABLE_MAGIC_URL}</label>
<!-- ENDIF -->
</dd>
<dd style="margin-{S_CONTENT_FLOW_BEGIN}: 90px; margin-top: 10px;"><strong>{L_OPTIONS}{L_COLON} </strong>{BBCODE_STATUS} :: {IMG_STATUS} :: {URL_STATUS} :: {SMILIES_STATUS}</dd>
<dd style="margin-{S_CONTENT_FLOW_BEGIN}: 90px; margin-top: 10px;"><strong>{L_OPTIONS}{L_COLON} </strong>{BBCODE_STATUS} :: {IMG_STATUS} :: {FLASH_STATUS} :: {URL_STATUS} :: {SMILIES_STATUS}</dd>
</dl>
</fieldset>

View file

@ -1,130 +0,0 @@
{% include('overall_header.html') %}
<a id="maincontent"></a>
<h1>{{ lang( 'EXTENSIONS_CATALOG') }}</h1>
<p>{{ lang( 'EXTENSIONS_CATALOG_EXPLAIN') }}</p>
<fieldset class="quick quick-left">
<span class="small"><a href="https://www.phpbb.com/go/customise/extensions/{{ PHPBB_MAJOR }}" target="_blank">{{ lang('BROWSE_EXTENSIONS_DATABASE') }}</a> &bull; <a href="javascript:phpbb.toggleDisplay('catalog_settings');">{{ lang('SETTINGS') }}</a></span>
</fieldset>
{% if pagination is defined %}
<div class="pagination top-pagination">
{% include('pagination.html') %}
</div>
{% endif %}
<form id="catalog_settings" method="post" action="{{ U_ACTION }}" style="display:none">
<fieldset style="clear: both;">
<legend>{{ lang('EXTENSIONS_CATALOG_SETTINGS') }}</legend>
<dl>
<dt><label for="enable_on_install">{{ lang('ENABLE_ON_INSTALL') }}{{ lang('COLON') }}</label></dt>
<dd>
<label><input type="radio" id="enable_on_install" name="enable_on_install" class="radio" value="1"{% if settings.enable_on_install %} checked="checked" {% endif %} /> {{ lang('YES') }}</label>
<label><input type="radio" name="enable_on_install" class="radio" value="0"{% if not settings.enable_on_install %} checked="checked" {% endif %} /> {{ lang('NO') }}</label>
</dd>
</dl>
<dl>
<dt><label for="purge_on_remove">{{ lang('PURGE_ON_REMOVE') }}{{ lang('COLON') }}</label></dt>
<dd>
<label><input type="radio" id="purge_on_remove" name="purge_on_remove" class="radio" value="1"{% if settings.purge_on_remove %} checked="checked" {% endif %} /> {{ lang('YES') }}</label>
<label><input type="radio" name="purge_on_remove" class="radio" value="0"{% if not settings.purge_on_remove %} checked="checked" {% endif %} /> {{ lang('NO') }}</label>
</dd>
</dl>
<dl>
<dt>
<label for="repositories">{{ lang('COMPOSER_REPOSITORIES') }}{{ lang('COLON') }}</label><br />
<span class="explain">
{{ lang('COMPOSER_REPOSITORIES_EXPLAIN') }}
</span>
</dt>
<dd>
<textarea id="repositories" name="repositories" rows="5" cols="30">{{ settings.repositories|join('\n') }}</textarea>
</dd>
</dl>
<dl>
<dt>
<label for="enable_packagist">{{ lang('ENABLE_PACKAGIST') }}{{ lang('COLON') }}</label><br />
<span class="explain">
<strong class="error">{{ lang('WARNING') }}{{ lang('COLON') }}</strong> {{ lang('ENABLE_PACKAGIST_EXPLAIN') }}
</span>
</dt>
<dd>
<label><input type="radio" id="enable_packagist" name="enable_packagist" class="radio" value="1"{% if settings.enable_packagist %} checked="checked" {% endif %} /> {{ lang('YES') }}</label>
<label><input type="radio" name="enable_packagist" class="radio" value="0"{% if not settings.enable_packagist %} checked="checked" {% endif %} /> {{ lang('NO') }}</label>
</dd>
</dl>
<dl>
<dt>
<label for="minimum_stability">{{ lang('COMPOSER_MINIMUM_STABILITY') }}{{ lang('COLON') }}</label><br />
<span class="explain">
<strong class="error">{{ lang('WARNING') }}{{ lang('COLON') }}</strong> {{ lang('COMPOSER_MINIMUM_STABILITY_EXPLAIN') }}
</span>
</dt>
<dd>
<select id="minimum_stability" name="minimum_stability">
{% for stability in settings.stabilities %}
<option value="{{ stability }}"{% if stability === settings.minimum_stability %} selected='selected'{% endif %}>{{ lang('STABILITY_' ~ stability|upper) }}</option>
{% endfor %}
</select>
</dd>
</dl>
<p class="submit-buttons">
<input class="button1" type="submit" name="update" value="{{ lang('SUBMIT') }}" />&nbsp;
<input class="button2" type="reset" name="reset" value="{{ lang('RESET') }}" />
<input type="hidden" name="action" value="set_catalog_settings" />
{{ S_FORM_TOKEN }}
</p>
</fieldset>
</form>
{% if extensions is empty %}
<tr>
<td colspan="4"><div class="errorbox notice">{{ lang('NO_EXTENSION_AVAILABLE') }}</div></td>
</tr>
{% else %}
<table class="table1">
<col class="row1" ><col class="row1" ><col class="row1" ><col class="row2" >
<thead>
<tr>
<th style="width: 25%;">{{ lang("EXTENSION_NAME") }}</th>
<th style="text-align: center; width: 10%;">{{ lang("VERSION") }}</th>
<th>{{ lang("DESCRIPTION") }}</th>
<th style="text-align: center; width: 15%;">{{ lang("EXTENSION_ACTIONS") }}</th>
</tr>
</thead>
<tbody>
{% for extension in extensions %}
<tr>
<td>
<strong>{{ extension.display_name }}</strong><br />
{{ extension.name }}
</td>
<td style="text-align: center">{{ extension.version }}</td>
<td>{{ extension.description }} &bull; <a href="{{ extension.url }}">{{ lang('HOMEPAGE') }}</a></td>
<td style="text-align: center">
{% if extension.name in managed_extensions %}
<span style="color: #228822;">{{ lang('INSTALLED') }}</span>
{% elseif extension.name in installed_extensions -%}
<span style="color: #BC2A4D;">{{ lang('INSTALLED_MANUALLY') }}</span>
(<a href="{{ U_ACTION }}&amp;action=manage&amp;extension={{ extension.composer_name|url_encode }}">{{ lang('MANAGE') }}</a>)
{% elseif not enabled -%}
<a href="{{ U_ACTION }}&amp;action=install&amp;extension={{ extension.composer_name|url_encode }}">{{ lang('INSTALL') }}</a>
{%- endif -%}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% if pagination is defined %}
<div class="pagination bottom-pagination">
{% include('pagination.html') %}
</div>
{% endif %}
{% include('overall_footer.html') %}

View file

@ -7,7 +7,7 @@
<p>{L_EXTENSIONS_EXPLAIN}</p>
<fieldset class="quick">
<span class="small"><a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE_ALL}</a> &bull; <a href="javascript:phpbb.toggleDisplay('version_check_settings');">{L_SETTINGS}</a></span>
<span class="small"><a href="https://www.phpbb.com/go/customise/extensions/3.3" target="_blank">{L_BROWSE_EXTENSIONS_DATABASE}</a> &bull; <a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE_ALL}</a> &bull; <a href="javascript:phpbb.toggleDisplay('version_check_settings');">{L_SETTINGS}</a></span>
</fieldset>
<form id="version_check_settings" method="post" action="{U_ACTION}" style="display:none">
@ -70,7 +70,7 @@
<td style="text-align: center;">
{% if data.S_VERSIONCHECK %}
<strong class="{% if data.S_UP_TO_DATE %}current-ext{% else %}outdated-ext{% endif %}">{{ data.META_VERSION }}</strong>
{% if not data.S_UP_TO_DATE %}{{ Icon('font', 'circle-exclamation', '', true, 'fas outdated-ext') }}{% endif %}
{% if not data.S_UP_TO_DATE %}<i class="fa fa-exclamation-circle outdated-ext" aria-hidden="true"></i>{% endif %}
{% else %}
{{ data.META_VERSION }}
{% endif %}
@ -92,42 +92,23 @@
</table>
<table class="table1">
<tbody>
<tr>
<th>{L_EXTENSION_INSTALLING_HEADLINE}</th>
<th>{L_EXTENSION_INSTALL_HEADLINE}</th>
</tr>
<tr>
<td class="row3">
<ol>
{% for step in lang_raw('EXTENSION_INSTALLING_EXPLAIN') %}
<li>{{ step }}</li>
{% endfor %}
</ol>
</td>
<td class="row3">{L_EXTENSION_INSTALL_EXPLAIN}</td>
</tr>
<tr>
<th>{L_EXTENSION_UPDATING_HEADLINE}</th>
<th>{L_EXTENSION_UPDATE_HEADLINE}</th>
</tr>
<tr>
<td class="row3">
<ol>
{% for step in lang_raw('EXTENSION_UPDATING_EXPLAIN') %}
<li>{{ step }}</li>
{% endfor %}
</ol>
</td>
<td class="row3">{L_EXTENSION_UPDATE_EXPLAIN}</td>
</tr>
<tr>
<th>{L_EXTENSION_REMOVING_HEADLINE}</th>
<th>{L_EXTENSION_REMOVE_HEADLINE}</th>
</tr>
<tr>
<td class="row3">
<ol>
{% for step in lang_raw('EXTENSION_REMOVING_EXPLAIN') %}
<li>{{ step }}</li>
{% endfor %}
</ol>
</td>
<td class="row3">{L_EXTENSION_REMOVE_EXPLAIN}</td>
</tr>
</tbody>
</table>

View file

@ -181,14 +181,7 @@
<!-- ENDIF -->
<dl>
<dt><label for="forum_style">{L_FORUM_STYLE}{L_COLON}</label></dt>
<dd>
<select id="forum_style" name="forum_style">
<option value="0">{{ lang('DEFAULT_STYLE') }}</option>
{% for style in S_STYLES_OPTIONS %}
<option value="{{ style.value }}"{% if style.selected %} selected="selected"{% endif %}>{{ style.label }}</option>
{% endfor %}
</select>
</dd>
<dd><select id="forum_style" name="forum_style"><option value="0">{L_DEFAULT_STYLE}</option>{S_STYLES_OPTIONS}</select></dd>
</dl>
<!-- EVENT acp_forums_main_settings_append -->
</fieldset>
@ -479,17 +472,7 @@
<tbody>
<!-- BEGIN forums -->
<tr>
<td class="folder">
<span class="fa-stack fa-2x">
{{ Icon('font', 'circle', '', true, 'fas fa-stack-2x') }}
{{ Icon('font', {
'link' : forums.S_FORUM_LINK,
'lock' : forums.S_FORUM_LOCKED,
'comments' : forums.S_SUBFORUMS,
'comment' : true,
}, '', true, 'fas fa-inverse fa-stack-1x') }}
</span>
</td>
<td class="folder">{forums.FOLDER_IMAGE}</td>
<td class="forum-desc">
<!-- IF forums.FORUM_IMAGE --><div style="float: {S_CONTENT_FLOW_BEGIN}; margin-right: 5px;">{forums.FORUM_IMAGE}</div><!-- ENDIF -->
<strong><!-- IF forums.S_FORUM_LINK -->{forums.FORUM_NAME}<!-- ELSE --><a href="{forums.U_FORUM}">{forums.FORUM_NAME}</a><!-- ENDIF --></strong>

View file

@ -0,0 +1,22 @@
<!-- INCLUDE overall_header.html -->
<h1>{L_COPY_PERMISSIONS}</h1>
<p>{L_COPY_PERMISSIONS_EXPLAIN}</p>
<p>{L_ACL_LINK}</p>
<form id="confirm" method="post" action="{S_COPY_ACTION}">
<fieldset>
<dl>
<dt><label for="forum_perm_from">{L_COPY_PERMISSIONS}{L_COLON}</label><br /><span>{L_COPY_PERMISSIONS_EXPLAIN}</span></dt>
<dd><select id="forum_perm_from" name="forum_perm_from"><option value="0">{L_NO_PERMISSIONS}</option>{S_FORUM_OPTIONS}</select></dd>
</dl>
<div style="text-align: center;">{S_FORM_TOKEN}{S_HIDDEN_FIELDS}
<input type="submit" name="update" value="{L_CONTINUE}" class="button2" />&nbsp;
</div>
</fieldset>
</form>
<!-- INCLUDE overall_footer.html -->

View file

@ -113,7 +113,7 @@
<legend>{L_GROUP_AVATAR}</legend>
<dl>
<dt><label>{L_CURRENT_IMAGE}{L_COLON}</label><br /><span>{L_AVATAR_EXPLAIN}</span></dt>
<dd class="c-avatar-box">{% if AVATAR_HTML %}{{ AVATAR_HTML }}{% else %}<img src="{{ ADMIN_ROOT_PATH ~ 'images/no_avatar.gif' }}" alt="">{% endif %}</dd>
<dd>{AVATAR}</dd>
<dd><label for="avatar_delete"><input type="checkbox" name="avatar_delete" id="avatar_delete" /> {L_DELETE_AVATAR}</label></dd>
</dl>
<dl>

View file

@ -8,11 +8,11 @@
<div class="send-stats-row">
<!-- EVENT acp_help_phpbb_stats_before -->
<div class="send-stats-tile">
<h2>{{ Icon('font', 'chart-column', lang('SEND_STATISTICS')) }}</h2>
<h2><i class="icon fa-bar-chart"></i>{L_SEND_STATISTICS}</h2>
<p>{L_EXPLAIN_SEND_STATISTICS}</p>
<div class="send-stats-row">
<div class="send-stats-data-row send-stats-data-only-row">
<a id="trigger-configlist" data-ajax="toggle_link" data-overlay="false" data-toggle-text="{L_HIDE_STATISTICS}"><span>{L_SHOW_STATISTICS}</span>{{ Icon('font', 'angle-down', '', true) }}</a>
<a id="trigger-configlist" data-ajax="toggle_link" data-overlay="false" data-toggle-text="{L_HIDE_STATISTICS}"><span>{L_SHOW_STATISTICS}</span><i class="icon fa-angle-down"></i></a>
</div>
<div class="send-stats-data-row">
<div class="configlist" id="configlist">

Some files were not shown because too many files have changed in this diff Show more